@povio/ui 5.0.0-rc.10 → 5.0.0-rc.12
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/README.md +6 -0
- package/dist/{AppCanvasPage-BIFYeEeS.d.ts → AppCanvasPage-BZ2mrKY4.d.ts} +5 -1
- package/dist/{AppCanvasPage-BEER5hHp.js → AppCanvasPage-DCjiFfQW.js} +1458 -362
- package/dist/CanvasComponentsFrame-CZXY0Dxi.js +21 -0
- package/dist/{ComponentGallery-CMFrbwEN.js → ComponentGallery-D4U5hXZL.js} +76 -15
- package/dist/{UIConfigurator-CTlq-hrG.js → UIConfigurator-CBU0G6rb.js} +1019 -817
- package/dist/config/app-canvas-tanstack.d.ts +1 -1
- package/dist/config/app-canvas-tanstack.js +1 -1
- package/dist/config/app-canvas.d.ts +2 -2
- package/dist/config/app-canvas.js +1 -1
- package/dist/config/ui-configurator-theme.js +1 -1
- package/dist/config/ui-configurator-vite.d.ts +2 -0
- package/dist/config/ui-configurator-vite.js +293 -4
- package/dist/config/ui-configurator.d.ts +1 -1
- package/dist/config/ui-configurator.js +2 -2
- package/dist/{configuration.context-DP4p1cIe.d.ts → configuration.context-iuZu-ie0.d.ts} +14 -0
- package/dist/groups-oQmSeqXn.js +18 -0
- package/dist/styles/app-canvas.css +617 -114
- package/dist/styles/configurator.css +461 -206
- package/dist/{theme-model-DtYPxNvH.js → theme-model-DtTsIxou.js} +3 -1
- package/package.json +1 -1
|
@@ -1,42 +1,19 @@
|
|
|
1
1
|
import { t as createLucideIcon } from "./createLucideIcon-LcezOE4z.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as inspectElement, c as HighlightOverlay, d as emptyConfiguration, f as useUIConfiguration, g as Moon, h as Pin, i as saveThemeCss, l as InspectorDetails, m as Plus, p as Sun, r as getThemeWriter, s as getBoxHighlights, t as UIConfigurationModal } from "./UIConfigurator-CBU0G6rb.js";
|
|
3
3
|
import { t as ChevronDown } from "./chevron-down-B4Pr8bD3.js";
|
|
4
4
|
import { t as ChevronRight } from "./chevron-right-3nKJR5Bb.js";
|
|
5
5
|
import { i as Search } from "./selectDesktop.cva-CHAMxhfO.js";
|
|
6
6
|
import { t as Upload } from "./upload-CXU83BJ4.js";
|
|
7
7
|
import { t as X } from "./x-B6vfz8Ps.js";
|
|
8
|
-
import {
|
|
8
|
+
import { c as $542a13ca2fa5b484$export$5b6b19405a83ff9d, n as $f2ff30fde7b014be$export$3ddf2d174ce01153 } from "./Dialog-CKLkS00H.js";
|
|
9
|
+
import { t as $2ec61d1d4f780267$export$a8a3e93435678ff9 } from "./Heading-nI1_VOaE.js";
|
|
10
|
+
import { t as Select } from "./Select-CgIhoWgk.js";
|
|
11
|
+
import { t as ThemeContext } from "./theme.context-B3wQDJ-i.js";
|
|
12
|
+
import { c as isEditableToken, i as exportCss, v as parseThemeCss } from "./theme-model-DtTsIxou.js";
|
|
13
|
+
import { t as componentArtboards } from "./groups-oQmSeqXn.js";
|
|
14
|
+
import { Suspense, lazy, memo, useCallback, useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
9
15
|
import { c } from "react/compiler-runtime";
|
|
10
16
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/code-xml.mjs
|
|
12
|
-
/**
|
|
13
|
-
* @license lucide-react v1.43.0 - ISC
|
|
14
|
-
*
|
|
15
|
-
* This source code is licensed under the ISC license.
|
|
16
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
17
|
-
*/
|
|
18
|
-
const __iconData$9 = {
|
|
19
|
-
name: "code-xml",
|
|
20
|
-
size: 24,
|
|
21
|
-
node: [
|
|
22
|
-
["path", {
|
|
23
|
-
d: "m18 16 4-4-4-4",
|
|
24
|
-
key: "1inbqp"
|
|
25
|
-
}],
|
|
26
|
-
["path", {
|
|
27
|
-
d: "m6 8-4 4 4 4",
|
|
28
|
-
key: "15zrgr"
|
|
29
|
-
}],
|
|
30
|
-
["path", {
|
|
31
|
-
d: "m14.5 4-5 16",
|
|
32
|
-
key: "e7oirm"
|
|
33
|
-
}]
|
|
34
|
-
],
|
|
35
|
-
aliases: ["code-2"]
|
|
36
|
-
};
|
|
37
|
-
__iconData$9.node;
|
|
38
|
-
const CodeXml = createLucideIcon(__iconData$9);
|
|
39
|
-
//#endregion
|
|
40
17
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/download.mjs
|
|
41
18
|
/**
|
|
42
19
|
* @license lucide-react v1.43.0 - ISC
|
|
@@ -44,7 +21,7 @@ const CodeXml = createLucideIcon(__iconData$9);
|
|
|
44
21
|
* This source code is licensed under the ISC license.
|
|
45
22
|
* See the LICENSE file in the root directory of this source tree.
|
|
46
23
|
*/
|
|
47
|
-
const __iconData$
|
|
24
|
+
const __iconData$10 = {
|
|
48
25
|
name: "download",
|
|
49
26
|
size: 24,
|
|
50
27
|
node: [
|
|
@@ -62,8 +39,8 @@ const __iconData$8 = {
|
|
|
62
39
|
}]
|
|
63
40
|
]
|
|
64
41
|
};
|
|
65
|
-
__iconData$
|
|
66
|
-
const Download = createLucideIcon(__iconData$
|
|
42
|
+
__iconData$10.node;
|
|
43
|
+
const Download = createLucideIcon(__iconData$10);
|
|
67
44
|
//#endregion
|
|
68
45
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/frame.mjs
|
|
69
46
|
/**
|
|
@@ -72,7 +49,7 @@ const Download = createLucideIcon(__iconData$8);
|
|
|
72
49
|
* This source code is licensed under the ISC license.
|
|
73
50
|
* See the LICENSE file in the root directory of this source tree.
|
|
74
51
|
*/
|
|
75
|
-
const __iconData$
|
|
52
|
+
const __iconData$9 = {
|
|
76
53
|
name: "frame",
|
|
77
54
|
size: 24,
|
|
78
55
|
node: [
|
|
@@ -106,8 +83,8 @@ const __iconData$7 = {
|
|
|
106
83
|
}]
|
|
107
84
|
]
|
|
108
85
|
};
|
|
109
|
-
__iconData$
|
|
110
|
-
const Frame = createLucideIcon(__iconData$
|
|
86
|
+
__iconData$9.node;
|
|
87
|
+
const Frame = createLucideIcon(__iconData$9);
|
|
111
88
|
//#endregion
|
|
112
89
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/hand.mjs
|
|
113
90
|
/**
|
|
@@ -116,7 +93,7 @@ const Frame = createLucideIcon(__iconData$7);
|
|
|
116
93
|
* This source code is licensed under the ISC license.
|
|
117
94
|
* See the LICENSE file in the root directory of this source tree.
|
|
118
95
|
*/
|
|
119
|
-
const __iconData$
|
|
96
|
+
const __iconData$8 = {
|
|
120
97
|
name: "hand",
|
|
121
98
|
size: 24,
|
|
122
99
|
node: [
|
|
@@ -138,8 +115,8 @@ const __iconData$6 = {
|
|
|
138
115
|
}]
|
|
139
116
|
]
|
|
140
117
|
};
|
|
141
|
-
__iconData$
|
|
142
|
-
const Hand = createLucideIcon(__iconData$
|
|
118
|
+
__iconData$8.node;
|
|
119
|
+
const Hand = createLucideIcon(__iconData$8);
|
|
143
120
|
//#endregion
|
|
144
121
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/monitor.mjs
|
|
145
122
|
/**
|
|
@@ -148,7 +125,7 @@ const Hand = createLucideIcon(__iconData$6);
|
|
|
148
125
|
* This source code is licensed under the ISC license.
|
|
149
126
|
* See the LICENSE file in the root directory of this source tree.
|
|
150
127
|
*/
|
|
151
|
-
const __iconData$
|
|
128
|
+
const __iconData$7 = {
|
|
152
129
|
name: "monitor",
|
|
153
130
|
size: 24,
|
|
154
131
|
node: [
|
|
@@ -176,8 +153,8 @@ const __iconData$5 = {
|
|
|
176
153
|
}]
|
|
177
154
|
]
|
|
178
155
|
};
|
|
179
|
-
__iconData$
|
|
180
|
-
const Monitor = createLucideIcon(__iconData$
|
|
156
|
+
__iconData$7.node;
|
|
157
|
+
const Monitor = createLucideIcon(__iconData$7);
|
|
181
158
|
//#endregion
|
|
182
159
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/mouse-pointer-2.mjs
|
|
183
160
|
/**
|
|
@@ -186,7 +163,7 @@ const Monitor = createLucideIcon(__iconData$5);
|
|
|
186
163
|
* This source code is licensed under the ISC license.
|
|
187
164
|
* See the LICENSE file in the root directory of this source tree.
|
|
188
165
|
*/
|
|
189
|
-
const __iconData$
|
|
166
|
+
const __iconData$6 = {
|
|
190
167
|
name: "mouse-pointer-2",
|
|
191
168
|
size: 24,
|
|
192
169
|
node: [["path", {
|
|
@@ -194,8 +171,8 @@ const __iconData$4 = {
|
|
|
194
171
|
key: "edeuup"
|
|
195
172
|
}]]
|
|
196
173
|
};
|
|
197
|
-
__iconData$
|
|
198
|
-
const MousePointer2 = createLucideIcon(__iconData$
|
|
174
|
+
__iconData$6.node;
|
|
175
|
+
const MousePointer2 = createLucideIcon(__iconData$6);
|
|
199
176
|
//#endregion
|
|
200
177
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/panel-left.mjs
|
|
201
178
|
/**
|
|
@@ -204,7 +181,7 @@ const MousePointer2 = createLucideIcon(__iconData$4);
|
|
|
204
181
|
* This source code is licensed under the ISC license.
|
|
205
182
|
* See the LICENSE file in the root directory of this source tree.
|
|
206
183
|
*/
|
|
207
|
-
const __iconData$
|
|
184
|
+
const __iconData$5 = {
|
|
208
185
|
name: "panel-left",
|
|
209
186
|
size: 24,
|
|
210
187
|
node: [["rect", {
|
|
@@ -220,8 +197,8 @@ const __iconData$3 = {
|
|
|
220
197
|
}]],
|
|
221
198
|
aliases: ["sidebar"]
|
|
222
199
|
};
|
|
223
|
-
__iconData$
|
|
224
|
-
const PanelLeft = createLucideIcon(__iconData$
|
|
200
|
+
__iconData$5.node;
|
|
201
|
+
const PanelLeft = createLucideIcon(__iconData$5);
|
|
225
202
|
//#endregion
|
|
226
203
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/panels-top-left.mjs
|
|
227
204
|
/**
|
|
@@ -230,7 +207,7 @@ const PanelLeft = createLucideIcon(__iconData$3);
|
|
|
230
207
|
* This source code is licensed under the ISC license.
|
|
231
208
|
* See the LICENSE file in the root directory of this source tree.
|
|
232
209
|
*/
|
|
233
|
-
const __iconData$
|
|
210
|
+
const __iconData$4 = {
|
|
234
211
|
name: "panels-top-left",
|
|
235
212
|
size: 24,
|
|
236
213
|
node: [
|
|
@@ -253,8 +230,29 @@ const __iconData$2 = {
|
|
|
253
230
|
],
|
|
254
231
|
aliases: ["layout"]
|
|
255
232
|
};
|
|
256
|
-
__iconData$
|
|
257
|
-
const PanelsTopLeft = createLucideIcon(__iconData$
|
|
233
|
+
__iconData$4.node;
|
|
234
|
+
const PanelsTopLeft = createLucideIcon(__iconData$4);
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/pencil.mjs
|
|
237
|
+
/**
|
|
238
|
+
* @license lucide-react v1.43.0 - ISC
|
|
239
|
+
*
|
|
240
|
+
* This source code is licensed under the ISC license.
|
|
241
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
242
|
+
*/
|
|
243
|
+
const __iconData$3 = {
|
|
244
|
+
name: "pencil",
|
|
245
|
+
size: 24,
|
|
246
|
+
node: [["path", {
|
|
247
|
+
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
|
248
|
+
key: "1a8usu"
|
|
249
|
+
}], ["path", {
|
|
250
|
+
d: "m15 5 4 4",
|
|
251
|
+
key: "1mk7zo"
|
|
252
|
+
}]]
|
|
253
|
+
};
|
|
254
|
+
__iconData$3.node;
|
|
255
|
+
const Pencil = createLucideIcon(__iconData$3);
|
|
258
256
|
//#endregion
|
|
259
257
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/scan-line.mjs
|
|
260
258
|
/**
|
|
@@ -263,7 +261,7 @@ const PanelsTopLeft = createLucideIcon(__iconData$2);
|
|
|
263
261
|
* This source code is licensed under the ISC license.
|
|
264
262
|
* See the LICENSE file in the root directory of this source tree.
|
|
265
263
|
*/
|
|
266
|
-
const __iconData$
|
|
264
|
+
const __iconData$2 = {
|
|
267
265
|
name: "scan-line",
|
|
268
266
|
size: 24,
|
|
269
267
|
node: [
|
|
@@ -289,8 +287,8 @@ const __iconData$1 = {
|
|
|
289
287
|
}]
|
|
290
288
|
]
|
|
291
289
|
};
|
|
292
|
-
__iconData$
|
|
293
|
-
const ScanLine = createLucideIcon(__iconData$
|
|
290
|
+
__iconData$2.node;
|
|
291
|
+
const ScanLine = createLucideIcon(__iconData$2);
|
|
294
292
|
//#endregion
|
|
295
293
|
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/settings-2.mjs
|
|
296
294
|
/**
|
|
@@ -299,7 +297,7 @@ const ScanLine = createLucideIcon(__iconData$1);
|
|
|
299
297
|
* This source code is licensed under the ISC license.
|
|
300
298
|
* See the LICENSE file in the root directory of this source tree.
|
|
301
299
|
*/
|
|
302
|
-
const __iconData = {
|
|
300
|
+
const __iconData$1 = {
|
|
303
301
|
name: "settings-2",
|
|
304
302
|
size: 24,
|
|
305
303
|
node: [
|
|
@@ -325,8 +323,937 @@ const __iconData = {
|
|
|
325
323
|
}]
|
|
326
324
|
]
|
|
327
325
|
};
|
|
326
|
+
__iconData$1.node;
|
|
327
|
+
const Settings2 = createLucideIcon(__iconData$1);
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region ../../node_modules/.bun/lucide-react@1.43.0+83d5fd7b249dbeef/node_modules/lucide-react/dist/esm/icons/trash.mjs
|
|
330
|
+
/**
|
|
331
|
+
* @license lucide-react v1.43.0 - ISC
|
|
332
|
+
*
|
|
333
|
+
* This source code is licensed under the ISC license.
|
|
334
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
335
|
+
*/
|
|
336
|
+
const __iconData = {
|
|
337
|
+
name: "trash",
|
|
338
|
+
size: 24,
|
|
339
|
+
node: [
|
|
340
|
+
["path", {
|
|
341
|
+
d: "M10 11v6",
|
|
342
|
+
key: "nco0om"
|
|
343
|
+
}],
|
|
344
|
+
["path", {
|
|
345
|
+
d: "M14 11v6",
|
|
346
|
+
key: "outv1u"
|
|
347
|
+
}],
|
|
348
|
+
["path", {
|
|
349
|
+
d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6",
|
|
350
|
+
key: "miytrc"
|
|
351
|
+
}],
|
|
352
|
+
["path", {
|
|
353
|
+
d: "M3 6h18",
|
|
354
|
+
key: "d0wm0j"
|
|
355
|
+
}],
|
|
356
|
+
["path", {
|
|
357
|
+
d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2",
|
|
358
|
+
key: "e791ji"
|
|
359
|
+
}]
|
|
360
|
+
],
|
|
361
|
+
aliases: ["trash-2"]
|
|
362
|
+
};
|
|
328
363
|
__iconData.node;
|
|
329
|
-
const
|
|
364
|
+
const Trash = createLucideIcon(__iconData);
|
|
365
|
+
//#endregion
|
|
366
|
+
//#region src/app-canvas/useWorkspaceConfiguration.ts
|
|
367
|
+
function useWorkspaceConfiguration(workspace, ready, generation, setManifest) {
|
|
368
|
+
const $ = c(15);
|
|
369
|
+
const { currentConfiguration, replaceConfiguration, defaults } = useUIConfiguration();
|
|
370
|
+
const loaded = useRef(null);
|
|
371
|
+
const t0 = workspace.id;
|
|
372
|
+
let t1;
|
|
373
|
+
if ($[0] !== defaults) {
|
|
374
|
+
t1 = JSON.stringify(defaults);
|
|
375
|
+
$[0] = defaults;
|
|
376
|
+
$[1] = t1;
|
|
377
|
+
} else t1 = $[1];
|
|
378
|
+
const key = `${generation}:${t0}:${t1}`;
|
|
379
|
+
let t2;
|
|
380
|
+
if ($[2] !== workspace.configuration) {
|
|
381
|
+
t2 = JSON.stringify(workspace.configuration);
|
|
382
|
+
$[2] = workspace.configuration;
|
|
383
|
+
$[3] = t2;
|
|
384
|
+
} else t2 = $[3];
|
|
385
|
+
const saved = t2;
|
|
386
|
+
let t3;
|
|
387
|
+
let t4;
|
|
388
|
+
if ($[4] !== currentConfiguration || $[5] !== defaults || $[6] !== key || $[7] !== ready || $[8] !== replaceConfiguration || $[9] !== saved || $[10] !== setManifest || $[11] !== workspace.configuration || $[12] !== workspace.id) {
|
|
389
|
+
t3 = () => {
|
|
390
|
+
if (!ready) return;
|
|
391
|
+
if (!loaded.current || loaded.current.key !== key || loaded.current.saved !== saved) {
|
|
392
|
+
const value = workspace.configuration ?? (loaded.current ? emptyConfiguration() : currentConfiguration);
|
|
393
|
+
const switchingWorkspace = !!loaded.current && loaded.current.workspaceId !== workspace.id;
|
|
394
|
+
loaded.current = {
|
|
395
|
+
key,
|
|
396
|
+
workspaceId: workspace.id,
|
|
397
|
+
saved
|
|
398
|
+
};
|
|
399
|
+
replaceConfiguration({
|
|
400
|
+
...value,
|
|
401
|
+
theme: {
|
|
402
|
+
light: Object.fromEntries(Object.entries(value.theme.light).filter((t5) => {
|
|
403
|
+
const [name, value_0] = t5;
|
|
404
|
+
return value_0 !== defaults.light[name];
|
|
405
|
+
})),
|
|
406
|
+
dark: Object.fromEntries(Object.entries(value.theme.dark).filter((t6) => {
|
|
407
|
+
const [name_0, value_1] = t6;
|
|
408
|
+
return value_1 !== defaults.dark[name_0];
|
|
409
|
+
})),
|
|
410
|
+
theme: Object.fromEntries(Object.entries(value.theme.theme).filter((t7) => {
|
|
411
|
+
const [name_1, value_2] = t7;
|
|
412
|
+
return value_2 !== defaults.theme[name_1];
|
|
413
|
+
}))
|
|
414
|
+
}
|
|
415
|
+
}, switchingWorkspace);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
const snapshot = {
|
|
419
|
+
...currentConfiguration,
|
|
420
|
+
theme: {
|
|
421
|
+
light: {
|
|
422
|
+
...defaults.light,
|
|
423
|
+
...currentConfiguration.theme.light
|
|
424
|
+
},
|
|
425
|
+
dark: {
|
|
426
|
+
...defaults.dark,
|
|
427
|
+
...currentConfiguration.theme.dark
|
|
428
|
+
},
|
|
429
|
+
theme: {
|
|
430
|
+
...defaults.theme,
|
|
431
|
+
...currentConfiguration.theme.theme
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
const serialized = JSON.stringify(snapshot);
|
|
436
|
+
if (serialized === saved) return;
|
|
437
|
+
loaded.current.saved = serialized;
|
|
438
|
+
setManifest((current) => ({
|
|
439
|
+
...current,
|
|
440
|
+
workspaces: current.workspaces.map((item) => item.id === workspace.id ? {
|
|
441
|
+
...item,
|
|
442
|
+
configuration: structuredClone(snapshot)
|
|
443
|
+
} : item)
|
|
444
|
+
}));
|
|
445
|
+
};
|
|
446
|
+
t4 = [
|
|
447
|
+
defaults,
|
|
448
|
+
key,
|
|
449
|
+
saved,
|
|
450
|
+
workspace.id,
|
|
451
|
+
workspace.configuration,
|
|
452
|
+
ready,
|
|
453
|
+
currentConfiguration,
|
|
454
|
+
replaceConfiguration,
|
|
455
|
+
setManifest
|
|
456
|
+
];
|
|
457
|
+
$[4] = currentConfiguration;
|
|
458
|
+
$[5] = defaults;
|
|
459
|
+
$[6] = key;
|
|
460
|
+
$[7] = ready;
|
|
461
|
+
$[8] = replaceConfiguration;
|
|
462
|
+
$[9] = saved;
|
|
463
|
+
$[10] = setManifest;
|
|
464
|
+
$[11] = workspace.configuration;
|
|
465
|
+
$[12] = workspace.id;
|
|
466
|
+
$[13] = t3;
|
|
467
|
+
$[14] = t4;
|
|
468
|
+
} else {
|
|
469
|
+
t3 = $[13];
|
|
470
|
+
t4 = $[14];
|
|
471
|
+
}
|
|
472
|
+
useLayoutEffect(t3, t4);
|
|
473
|
+
}
|
|
474
|
+
//#endregion
|
|
475
|
+
//#region src/app-canvas/SaveCanvasTheme.tsx
|
|
476
|
+
/** Uses the same development-only writer as the configurator's CSS export. */
|
|
477
|
+
function SaveCanvasTheme() {
|
|
478
|
+
const { active, defaults } = useUIConfiguration();
|
|
479
|
+
const [writer, setWriter] = useState(null);
|
|
480
|
+
const [saving, setSaving] = useState(false);
|
|
481
|
+
const [message, setMessage] = useState("");
|
|
482
|
+
const [savedTheme, setSavedTheme] = useState(defaults);
|
|
483
|
+
useEffect(() => setWriter(getThemeWriter()), []);
|
|
484
|
+
useEffect(() => setSavedTheme(defaults), [defaults]);
|
|
485
|
+
const css = exportCss(active.theme, defaults);
|
|
486
|
+
const exported = parseThemeCss(css);
|
|
487
|
+
const currentTheme = {
|
|
488
|
+
light: {
|
|
489
|
+
...defaults.light,
|
|
490
|
+
...exported.light
|
|
491
|
+
},
|
|
492
|
+
dark: {
|
|
493
|
+
...defaults.dark,
|
|
494
|
+
...exported.dark
|
|
495
|
+
},
|
|
496
|
+
theme: {
|
|
497
|
+
...defaults.theme,
|
|
498
|
+
...exported.theme
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
const hasChanges = [
|
|
502
|
+
"light",
|
|
503
|
+
"dark",
|
|
504
|
+
"theme"
|
|
505
|
+
].some((mode) => {
|
|
506
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(currentTheme[mode]), ...Object.keys(savedTheme[mode])])].some((key) => currentTheme[mode][key]?.trim() !== savedTheme[mode][key]?.trim());
|
|
507
|
+
});
|
|
508
|
+
useEffect(() => setMessage(""), [active.theme]);
|
|
509
|
+
if (!writer || !hasChanges && !saving) return null;
|
|
510
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
511
|
+
className: "povio-canvas-save-theme",
|
|
512
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
513
|
+
disabled: saving,
|
|
514
|
+
title: `Save current CSS settings to ${writer.file}`,
|
|
515
|
+
onClick: async () => {
|
|
516
|
+
setSaving(true);
|
|
517
|
+
setMessage("");
|
|
518
|
+
try {
|
|
519
|
+
await saveThemeCss(writer, css);
|
|
520
|
+
setSavedTheme(currentTheme);
|
|
521
|
+
setMessage(`Saved CSS to ${writer.file}.`);
|
|
522
|
+
} catch (error) {
|
|
523
|
+
setMessage(error instanceof Error ? error.message : "Could not save CSS settings.");
|
|
524
|
+
} finally {
|
|
525
|
+
setSaving(false);
|
|
526
|
+
}
|
|
527
|
+
},
|
|
528
|
+
children: saving ? "Saving theme…" : "Save theme to repo"
|
|
529
|
+
}), message && /* @__PURE__ */ jsx("p", {
|
|
530
|
+
role: "status",
|
|
531
|
+
children: message
|
|
532
|
+
})]
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region src/app-canvas/manifest.ts
|
|
537
|
+
function createCanvasWorkspace(name, id) {
|
|
538
|
+
return {
|
|
539
|
+
id,
|
|
540
|
+
name: name.trim() || "Workspace",
|
|
541
|
+
enabledPages: null,
|
|
542
|
+
positions: {}
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function createCanvasManifest() {
|
|
546
|
+
return {
|
|
547
|
+
version: 2,
|
|
548
|
+
workspaces: [createCanvasWorkspace("All pages", "default")],
|
|
549
|
+
activeWorkspaceId: "default",
|
|
550
|
+
examples: {},
|
|
551
|
+
breakpoint: "desktop"
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
function isRecord(value) {
|
|
555
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
556
|
+
}
|
|
557
|
+
function isJSON(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
558
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
559
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
560
|
+
if (typeof value !== "object" || depth > 30 || ancestors.has(value)) return false;
|
|
561
|
+
ancestors.add(value);
|
|
562
|
+
const valid = Object.values(value).every((child) => isJSON(child, ancestors, depth + 1));
|
|
563
|
+
ancestors.delete(value);
|
|
564
|
+
return valid;
|
|
565
|
+
}
|
|
566
|
+
function safeJSON(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
567
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
568
|
+
if (typeof value === "number") return Number.isFinite(value);
|
|
569
|
+
if (typeof value !== "object" || depth > 30 || ancestors.has(value)) return false;
|
|
570
|
+
if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return false;
|
|
571
|
+
ancestors.add(value);
|
|
572
|
+
const valid = Object.entries(value).every(([key, child]) => ![
|
|
573
|
+
"__proto__",
|
|
574
|
+
"prototype",
|
|
575
|
+
"constructor"
|
|
576
|
+
].includes(key) && safeJSON(child, ancestors, depth + 1));
|
|
577
|
+
ancestors.delete(value);
|
|
578
|
+
return valid;
|
|
579
|
+
}
|
|
580
|
+
const stringMap = (value) => isRecord(value) && Object.values(value).every((item) => typeof item === "string");
|
|
581
|
+
const variantValue = (value) => value === null || typeof value === "string" || typeof value === "boolean";
|
|
582
|
+
function validCvaEdits(value) {
|
|
583
|
+
return isRecord(value) && Object.entries(value).every(([slot, definition]) => {
|
|
584
|
+
if (!/^[a-zA-Z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]*$/.test(slot) || !isRecord(definition) || !Array.isArray(definition.base) || !definition.base.every((item) => typeof item === "string") || !isRecord(definition.config)) return false;
|
|
585
|
+
const config = definition.config;
|
|
586
|
+
return isRecord(config.variants) && Object.values(config.variants).every(stringMap) && isRecord(config.defaultVariants) && Object.values(config.defaultVariants).every(variantValue) && Array.isArray(config.compoundVariants) && config.compoundVariants.every((compound) => isRecord(compound) && Object.values(compound).every((item) => variantValue(item) || Array.isArray(item) && (item.every((part) => typeof part === "string") || item.every((part) => typeof part === "boolean"))));
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
/** Returns an independent JSON configuration, or undefined for invalid/unset overrides. */
|
|
590
|
+
function parseCanvasConfiguration(value) {
|
|
591
|
+
if (!isRecord(value) || !safeJSON(value) || !isRecord(value.theme) || ![
|
|
592
|
+
"light",
|
|
593
|
+
"dark",
|
|
594
|
+
"theme"
|
|
595
|
+
].every((key) => stringMap(value.theme && value.theme[key])) || !isRecord(value.config) || value.overrides !== void 0 && !validCvaEdits(value.overrides)) return void 0;
|
|
596
|
+
return JSON.parse(JSON.stringify(value));
|
|
597
|
+
}
|
|
598
|
+
function parsePositions(input) {
|
|
599
|
+
return Object.fromEntries(Object.entries(isRecord(input) ? input : {}).flatMap(([breakpoint, entries]) => {
|
|
600
|
+
if (!isRecord(entries)) return [];
|
|
601
|
+
return [[breakpoint, Object.fromEntries(Object.entries(entries).flatMap(([id, point]) => isRecord(point) && typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y) ? [[id, {
|
|
602
|
+
x: point.x,
|
|
603
|
+
y: point.y
|
|
604
|
+
}]] : []))]];
|
|
605
|
+
}));
|
|
606
|
+
}
|
|
607
|
+
/** Sanitize either stored JSON text or an imported value, migrating v1 positions into the default workspace. */
|
|
608
|
+
function parseCanvasManifest(input) {
|
|
609
|
+
const fallback = createCanvasManifest();
|
|
610
|
+
let value = input;
|
|
611
|
+
if (typeof value === "string") try {
|
|
612
|
+
value = JSON.parse(value);
|
|
613
|
+
} catch {
|
|
614
|
+
return fallback;
|
|
615
|
+
}
|
|
616
|
+
if (!isRecord(value) || value.version !== 1 && value.version !== 2) return fallback;
|
|
617
|
+
const examples = Object.fromEntries(Object.entries(isRecord(value.examples) ? value.examples : {}).flatMap(([id, example]) => {
|
|
618
|
+
if (!isRecord(example)) return [];
|
|
619
|
+
const clean = {};
|
|
620
|
+
if (typeof example.title === "string") clean.title = example.title;
|
|
621
|
+
if (isRecord(example.params)) clean.params = Object.fromEntries(Object.entries(example.params).filter((entry) => typeof entry[1] === "string"));
|
|
622
|
+
if (isRecord(example.search)) clean.search = Object.fromEntries(Object.entries(example.search).filter(([, item]) => isJSON(item)));
|
|
623
|
+
return [[id, clean]];
|
|
624
|
+
}));
|
|
625
|
+
const workspaces = [];
|
|
626
|
+
const ids = /* @__PURE__ */ new Set();
|
|
627
|
+
if (value.version === 1) workspaces.push({
|
|
628
|
+
...createCanvasWorkspace("All pages", "default"),
|
|
629
|
+
positions: parsePositions(value.positions)
|
|
630
|
+
});
|
|
631
|
+
else if (Array.isArray(value.workspaces)) for (const entry of value.workspaces) {
|
|
632
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || !entry.id.trim() || ids.has(entry.id)) continue;
|
|
633
|
+
ids.add(entry.id);
|
|
634
|
+
const configuration = parseCanvasConfiguration(entry.configuration);
|
|
635
|
+
workspaces.push({
|
|
636
|
+
id: entry.id,
|
|
637
|
+
name: typeof entry.name === "string" && entry.name.trim() ? entry.name.trim() : "Workspace",
|
|
638
|
+
enabledPages: Array.isArray(entry.enabledPages) ? [...new Set(entry.enabledPages.filter((id) => typeof id === "string" && id.length > 0))] : null,
|
|
639
|
+
positions: parsePositions(entry.positions),
|
|
640
|
+
...configuration ? { configuration } : {}
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
if (!workspaces.length) workspaces.push(createCanvasWorkspace("All pages", "default"));
|
|
644
|
+
return {
|
|
645
|
+
version: 2,
|
|
646
|
+
workspaces,
|
|
647
|
+
activeWorkspaceId: typeof value.activeWorkspaceId === "string" && workspaces.some((workspace) => workspace.id === value.activeWorkspaceId) ? value.activeWorkspaceId : workspaces[0].id,
|
|
648
|
+
examples,
|
|
649
|
+
breakpoint: typeof value.breakpoint === "string" && value.breakpoint.length > 0 ? value.breakpoint : fallback.breakpoint
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
//#endregion
|
|
653
|
+
//#region src/app-canvas/WorkspaceControls.tsx
|
|
654
|
+
function WorkspaceControls(t0) {
|
|
655
|
+
const $ = c(81);
|
|
656
|
+
const { manifest, setManifest, pages, disabled } = t0;
|
|
657
|
+
const createTrigger = useRef(null);
|
|
658
|
+
const pagesTrigger = useRef(null);
|
|
659
|
+
const editTrigger = useRef(null);
|
|
660
|
+
let t1;
|
|
661
|
+
if ($[0] !== manifest.activeWorkspaceId) {
|
|
662
|
+
t1 = (item) => item.id === manifest.activeWorkspaceId;
|
|
663
|
+
$[0] = manifest.activeWorkspaceId;
|
|
664
|
+
$[1] = t1;
|
|
665
|
+
} else t1 = $[1];
|
|
666
|
+
const workspace = manifest.workspaces.find(t1);
|
|
667
|
+
const [action, setAction] = useState(null);
|
|
668
|
+
const [name, setName] = useState("");
|
|
669
|
+
const [draftPages, setDraftPages] = useState(null);
|
|
670
|
+
const [query, setQuery] = useState("");
|
|
671
|
+
let t2;
|
|
672
|
+
if ($[2] !== setAction) {
|
|
673
|
+
t2 = () => {
|
|
674
|
+
setAction(null);
|
|
675
|
+
};
|
|
676
|
+
$[2] = setAction;
|
|
677
|
+
$[3] = t2;
|
|
678
|
+
} else t2 = $[3];
|
|
679
|
+
useEffect(t2, [workspace.id]);
|
|
680
|
+
let t3;
|
|
681
|
+
if ($[4] !== disabled || $[5] !== setAction) {
|
|
682
|
+
t3 = () => {
|
|
683
|
+
if (disabled) setAction(null);
|
|
684
|
+
};
|
|
685
|
+
$[4] = disabled;
|
|
686
|
+
$[5] = setAction;
|
|
687
|
+
$[6] = t3;
|
|
688
|
+
} else t3 = $[6];
|
|
689
|
+
let t4;
|
|
690
|
+
if ($[7] !== disabled) {
|
|
691
|
+
t4 = [disabled];
|
|
692
|
+
$[7] = disabled;
|
|
693
|
+
$[8] = t4;
|
|
694
|
+
} else t4 = $[8];
|
|
695
|
+
useEffect(t3, t4);
|
|
696
|
+
const open = (next) => {
|
|
697
|
+
setName(next === "create" ? "" : workspace.name);
|
|
698
|
+
setDraftPages(next === "create" ? [] : workspace.enabledPages);
|
|
699
|
+
setQuery("");
|
|
700
|
+
setAction(next);
|
|
701
|
+
};
|
|
702
|
+
let t5;
|
|
703
|
+
if ($[9] !== draftPages) {
|
|
704
|
+
t5 = (id) => draftPages === null || draftPages.includes(id);
|
|
705
|
+
$[9] = draftPages;
|
|
706
|
+
$[10] = t5;
|
|
707
|
+
} else t5 = $[10];
|
|
708
|
+
const enabled = t5;
|
|
709
|
+
const title = action === "create" ? "Create workspace" : action === "rename" ? "Edit workspace" : action === "delete" ? "Delete workspace?" : "Manage pages";
|
|
710
|
+
const save = () => {
|
|
711
|
+
if (disabled || !action) return;
|
|
712
|
+
if ((action === "create" || action === "rename") && !name.trim()) return;
|
|
713
|
+
const created = action === "create" ? {
|
|
714
|
+
...createCanvasWorkspace(name.trim(), crypto.randomUUID()),
|
|
715
|
+
enabledPages: draftPages
|
|
716
|
+
} : null;
|
|
717
|
+
setManifest((current) => {
|
|
718
|
+
if (created) return {
|
|
719
|
+
...current,
|
|
720
|
+
workspaces: [...current.workspaces, created],
|
|
721
|
+
activeWorkspaceId: created.id
|
|
722
|
+
};
|
|
723
|
+
if (action === "delete") {
|
|
724
|
+
if (current.workspaces.length < 2) return current;
|
|
725
|
+
const remaining = current.workspaces.filter((item_0) => item_0.id !== workspace.id);
|
|
726
|
+
return {
|
|
727
|
+
...current,
|
|
728
|
+
workspaces: remaining,
|
|
729
|
+
activeWorkspaceId: remaining[0].id
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
return {
|
|
733
|
+
...current,
|
|
734
|
+
workspaces: current.workspaces.map((item_1) => item_1.id === workspace.id ? {
|
|
735
|
+
...item_1,
|
|
736
|
+
...action === "rename" ? { name: name.trim() } : { enabledPages: draftPages }
|
|
737
|
+
} : item_1)
|
|
738
|
+
};
|
|
739
|
+
});
|
|
740
|
+
setAction(null);
|
|
741
|
+
};
|
|
742
|
+
let t6;
|
|
743
|
+
if ($[11] !== query) {
|
|
744
|
+
t6 = (page) => `${page.title} ${page.path}`.toLowerCase().includes(query.toLowerCase());
|
|
745
|
+
$[11] = query;
|
|
746
|
+
$[12] = t6;
|
|
747
|
+
} else t6 = $[12];
|
|
748
|
+
const visiblePages = pages.filter(t6);
|
|
749
|
+
const t7 = workspace.id;
|
|
750
|
+
let t8;
|
|
751
|
+
if ($[13] !== manifest.workspaces) {
|
|
752
|
+
t8 = manifest.workspaces.map(_temp);
|
|
753
|
+
$[13] = manifest.workspaces;
|
|
754
|
+
$[14] = t8;
|
|
755
|
+
} else t8 = $[14];
|
|
756
|
+
let t9;
|
|
757
|
+
if ($[15] !== setManifest) {
|
|
758
|
+
t9 = (id_0) => {
|
|
759
|
+
if (id_0 !== null) setManifest((current_0) => ({
|
|
760
|
+
...current_0,
|
|
761
|
+
activeWorkspaceId: String(id_0)
|
|
762
|
+
}));
|
|
763
|
+
};
|
|
764
|
+
$[15] = setManifest;
|
|
765
|
+
$[16] = t9;
|
|
766
|
+
} else t9 = $[16];
|
|
767
|
+
let t10;
|
|
768
|
+
if ($[17] !== open) {
|
|
769
|
+
t10 = () => open("create");
|
|
770
|
+
$[17] = open;
|
|
771
|
+
$[18] = t10;
|
|
772
|
+
} else t10 = $[18];
|
|
773
|
+
let t11;
|
|
774
|
+
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
|
775
|
+
t11 = /* @__PURE__ */ jsx(Plus, { size: 15 });
|
|
776
|
+
$[19] = t11;
|
|
777
|
+
} else t11 = $[19];
|
|
778
|
+
let t12;
|
|
779
|
+
if ($[20] !== t10) {
|
|
780
|
+
t12 = /* @__PURE__ */ jsx("button", {
|
|
781
|
+
ref: createTrigger,
|
|
782
|
+
"aria-label": "Add workspace",
|
|
783
|
+
title: "Add workspace",
|
|
784
|
+
onClick: t10,
|
|
785
|
+
children: t11
|
|
786
|
+
});
|
|
787
|
+
$[20] = t10;
|
|
788
|
+
$[21] = t12;
|
|
789
|
+
} else t12 = $[21];
|
|
790
|
+
let t13;
|
|
791
|
+
if ($[22] !== open) {
|
|
792
|
+
t13 = () => open("rename");
|
|
793
|
+
$[22] = open;
|
|
794
|
+
$[23] = t13;
|
|
795
|
+
} else t13 = $[23];
|
|
796
|
+
let t14;
|
|
797
|
+
if ($[24] === Symbol.for("react.memo_cache_sentinel")) {
|
|
798
|
+
t14 = /* @__PURE__ */ jsx(Pencil, { size: 14 });
|
|
799
|
+
$[24] = t14;
|
|
800
|
+
} else t14 = $[24];
|
|
801
|
+
let t15;
|
|
802
|
+
if ($[25] !== t13) {
|
|
803
|
+
t15 = /* @__PURE__ */ jsx("button", {
|
|
804
|
+
ref: editTrigger,
|
|
805
|
+
"aria-label": "Rename workspace",
|
|
806
|
+
title: "Edit workspace",
|
|
807
|
+
onClick: t13,
|
|
808
|
+
children: t14
|
|
809
|
+
});
|
|
810
|
+
$[25] = t13;
|
|
811
|
+
$[26] = t15;
|
|
812
|
+
} else t15 = $[26];
|
|
813
|
+
let t16;
|
|
814
|
+
if ($[27] !== open) {
|
|
815
|
+
t16 = () => open("pages");
|
|
816
|
+
$[27] = open;
|
|
817
|
+
$[28] = t16;
|
|
818
|
+
} else t16 = $[28];
|
|
819
|
+
const t17 = pages.filter((page_0) => workspace.enabledPages === null || workspace.enabledPages.includes(page_0.id));
|
|
820
|
+
let t18;
|
|
821
|
+
if ($[29] !== pages.length || $[30] !== t17) {
|
|
822
|
+
t18 = /* @__PURE__ */ jsxs("span", { children: [
|
|
823
|
+
t17.length,
|
|
824
|
+
"/",
|
|
825
|
+
pages.length
|
|
826
|
+
] });
|
|
827
|
+
$[29] = pages.length;
|
|
828
|
+
$[30] = t17;
|
|
829
|
+
$[31] = t18;
|
|
830
|
+
} else t18 = $[31];
|
|
831
|
+
let t19;
|
|
832
|
+
if ($[32] !== t16 || $[33] !== t18) {
|
|
833
|
+
t19 = /* @__PURE__ */ jsx("div", {
|
|
834
|
+
className: "povio-canvas-workspace-actions",
|
|
835
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
836
|
+
ref: pagesTrigger,
|
|
837
|
+
onClick: t16,
|
|
838
|
+
children: [
|
|
839
|
+
"Manage pages",
|
|
840
|
+
" ",
|
|
841
|
+
t18
|
|
842
|
+
]
|
|
843
|
+
})
|
|
844
|
+
});
|
|
845
|
+
$[32] = t16;
|
|
846
|
+
$[33] = t18;
|
|
847
|
+
$[34] = t19;
|
|
848
|
+
} else t19 = $[34];
|
|
849
|
+
const T0 = $542a13ca2fa5b484$export$5b6b19405a83ff9d;
|
|
850
|
+
const t20 = action === "create" ? createTrigger : action === "pages" ? pagesTrigger : editTrigger;
|
|
851
|
+
const t21 = "bottom start";
|
|
852
|
+
const t22 = 6;
|
|
853
|
+
const t23 = "povio-canvas-workspace-popover";
|
|
854
|
+
const t24 = action !== null;
|
|
855
|
+
let t25;
|
|
856
|
+
if ($[35] !== setAction) {
|
|
857
|
+
t25 = (isOpen) => {
|
|
858
|
+
if (!isOpen) setAction(null);
|
|
859
|
+
};
|
|
860
|
+
$[35] = setAction;
|
|
861
|
+
$[36] = t25;
|
|
862
|
+
} else t25 = $[36];
|
|
863
|
+
const T1 = $f2ff30fde7b014be$export$3ddf2d174ce01153;
|
|
864
|
+
const t26 = action === "delete" ? "alertdialog" : "dialog";
|
|
865
|
+
let t27;
|
|
866
|
+
if ($[37] !== save) {
|
|
867
|
+
t27 = (event) => {
|
|
868
|
+
event.preventDefault();
|
|
869
|
+
save();
|
|
870
|
+
};
|
|
871
|
+
$[37] = save;
|
|
872
|
+
$[38] = t27;
|
|
873
|
+
} else t27 = $[38];
|
|
874
|
+
let t28;
|
|
875
|
+
if ($[39] !== title) {
|
|
876
|
+
t28 = /* @__PURE__ */ jsx($2ec61d1d4f780267$export$a8a3e93435678ff9, {
|
|
877
|
+
slot: "title",
|
|
878
|
+
children: title
|
|
879
|
+
});
|
|
880
|
+
$[39] = title;
|
|
881
|
+
$[40] = t28;
|
|
882
|
+
} else t28 = $[40];
|
|
883
|
+
let t29;
|
|
884
|
+
if ($[41] !== setAction) {
|
|
885
|
+
t29 = () => setAction(null);
|
|
886
|
+
$[41] = setAction;
|
|
887
|
+
$[42] = t29;
|
|
888
|
+
} else t29 = $[42];
|
|
889
|
+
let t30;
|
|
890
|
+
if ($[43] === Symbol.for("react.memo_cache_sentinel")) {
|
|
891
|
+
t30 = /* @__PURE__ */ jsx(X, { size: 12 });
|
|
892
|
+
$[43] = t30;
|
|
893
|
+
} else t30 = $[43];
|
|
894
|
+
let t31;
|
|
895
|
+
if ($[44] !== t29) {
|
|
896
|
+
t31 = /* @__PURE__ */ jsx("button", {
|
|
897
|
+
type: "button",
|
|
898
|
+
"aria-label": "Close workspace dialog",
|
|
899
|
+
onClick: t29,
|
|
900
|
+
children: t30
|
|
901
|
+
});
|
|
902
|
+
$[44] = t29;
|
|
903
|
+
$[45] = t31;
|
|
904
|
+
} else t31 = $[45];
|
|
905
|
+
let t32;
|
|
906
|
+
if ($[46] !== t28 || $[47] !== t31) {
|
|
907
|
+
t32 = /* @__PURE__ */ jsxs("header", {
|
|
908
|
+
className: "povio-canvas-workspace-popover-heading",
|
|
909
|
+
children: [t28, t31]
|
|
910
|
+
});
|
|
911
|
+
$[46] = t28;
|
|
912
|
+
$[47] = t31;
|
|
913
|
+
$[48] = t32;
|
|
914
|
+
} else t32 = $[48];
|
|
915
|
+
const t33 = action === "delete" ? /* @__PURE__ */ jsxs("p", { children: [
|
|
916
|
+
"Delete “",
|
|
917
|
+
workspace.name,
|
|
918
|
+
"” and its saved layout and theme?"
|
|
919
|
+
] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [(action === "create" || action === "rename") && /* @__PURE__ */ jsxs("label", { children: ["Workspace name", /* @__PURE__ */ jsx("input", {
|
|
920
|
+
autoFocus: true,
|
|
921
|
+
value: name,
|
|
922
|
+
maxLength: 80,
|
|
923
|
+
placeholder: "Workspace name",
|
|
924
|
+
onChange: (event_0) => setName(event_0.target.value),
|
|
925
|
+
required: true
|
|
926
|
+
})] }), (action === "create" || action === "pages") && /* @__PURE__ */ jsxs("div", {
|
|
927
|
+
role: "group",
|
|
928
|
+
"aria-label": "Enabled pages",
|
|
929
|
+
className: "povio-canvas-popover-pages",
|
|
930
|
+
children: [
|
|
931
|
+
/* @__PURE__ */ jsxs("div", {
|
|
932
|
+
className: "povio-canvas-popover-page-tools",
|
|
933
|
+
children: [
|
|
934
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
935
|
+
pages.filter((page_1) => enabled(page_1.id)).length,
|
|
936
|
+
"/",
|
|
937
|
+
pages.length,
|
|
938
|
+
" pages"
|
|
939
|
+
] }),
|
|
940
|
+
/* @__PURE__ */ jsx("button", {
|
|
941
|
+
type: "button",
|
|
942
|
+
onClick: () => setDraftPages(null),
|
|
943
|
+
children: "Enable all"
|
|
944
|
+
}),
|
|
945
|
+
/* @__PURE__ */ jsx("button", {
|
|
946
|
+
type: "button",
|
|
947
|
+
onClick: () => setDraftPages([]),
|
|
948
|
+
children: "Disable all"
|
|
949
|
+
})
|
|
950
|
+
]
|
|
951
|
+
}),
|
|
952
|
+
/* @__PURE__ */ jsxs("label", {
|
|
953
|
+
className: "povio-canvas-popover-search",
|
|
954
|
+
children: [/* @__PURE__ */ jsx(Search, { size: 12 }), /* @__PURE__ */ jsx("input", {
|
|
955
|
+
"aria-label": "Find workspace pages",
|
|
956
|
+
placeholder: "Find pages…",
|
|
957
|
+
value: query,
|
|
958
|
+
onChange: (event_1) => setQuery(event_1.target.value)
|
|
959
|
+
})]
|
|
960
|
+
}),
|
|
961
|
+
/* @__PURE__ */ jsxs("div", {
|
|
962
|
+
className: "povio-canvas-popover-page-list",
|
|
963
|
+
children: [visiblePages.map((page_2) => /* @__PURE__ */ jsxs("label", { children: [/* @__PURE__ */ jsx("input", {
|
|
964
|
+
type: "checkbox",
|
|
965
|
+
checked: enabled(page_2.id),
|
|
966
|
+
onChange: (event_2) => {
|
|
967
|
+
const ids = draftPages ?? pages.map(_temp2);
|
|
968
|
+
setDraftPages(event_2.target.checked ? [.../* @__PURE__ */ new Set([...ids, page_2.id])] : ids.filter((id_1) => id_1 !== page_2.id));
|
|
969
|
+
}
|
|
970
|
+
}), /* @__PURE__ */ jsx("span", { children: page_2.title })] }, page_2.id)), !visiblePages.length && /* @__PURE__ */ jsx("p", { children: "No matching pages." })]
|
|
971
|
+
})
|
|
972
|
+
]
|
|
973
|
+
})] });
|
|
974
|
+
let t34;
|
|
975
|
+
if ($[49] !== action || $[50] !== manifest.workspaces.length || $[51] !== setAction) {
|
|
976
|
+
t34 = action === "rename" ? /* @__PURE__ */ jsxs("button", {
|
|
977
|
+
type: "button",
|
|
978
|
+
className: "povio-canvas-workspace-delete",
|
|
979
|
+
disabled: manifest.workspaces.length < 2,
|
|
980
|
+
onClick: () => setAction("delete"),
|
|
981
|
+
children: [/* @__PURE__ */ jsx(Trash, { size: 12 }), " Delete workspace"]
|
|
982
|
+
}) : /* @__PURE__ */ jsx("button", {
|
|
983
|
+
type: "button",
|
|
984
|
+
autoFocus: action === "delete",
|
|
985
|
+
onClick: () => action === "delete" ? setAction("rename") : setAction(null),
|
|
986
|
+
children: action === "delete" ? "Back" : "Cancel"
|
|
987
|
+
});
|
|
988
|
+
$[49] = action;
|
|
989
|
+
$[50] = manifest.workspaces.length;
|
|
990
|
+
$[51] = setAction;
|
|
991
|
+
$[52] = t34;
|
|
992
|
+
} else t34 = $[52];
|
|
993
|
+
const t35 = action === "delete" ? "is-danger" : "is-primary";
|
|
994
|
+
let t36;
|
|
995
|
+
if ($[53] !== action || $[54] !== disabled || $[55] !== name) {
|
|
996
|
+
t36 = disabled || (action === "create" || action === "rename") && !name.trim();
|
|
997
|
+
$[53] = action;
|
|
998
|
+
$[54] = disabled;
|
|
999
|
+
$[55] = name;
|
|
1000
|
+
$[56] = t36;
|
|
1001
|
+
} else t36 = $[56];
|
|
1002
|
+
const t37 = action === "create" ? "Create workspace" : action === "rename" ? "Save name" : action === "delete" ? "Delete" : "Save pages";
|
|
1003
|
+
let t38;
|
|
1004
|
+
if ($[57] !== t35 || $[58] !== t36 || $[59] !== t37) {
|
|
1005
|
+
t38 = /* @__PURE__ */ jsx("button", {
|
|
1006
|
+
type: "submit",
|
|
1007
|
+
className: t35,
|
|
1008
|
+
disabled: t36,
|
|
1009
|
+
children: t37
|
|
1010
|
+
});
|
|
1011
|
+
$[57] = t35;
|
|
1012
|
+
$[58] = t36;
|
|
1013
|
+
$[59] = t37;
|
|
1014
|
+
$[60] = t38;
|
|
1015
|
+
} else t38 = $[60];
|
|
1016
|
+
let t39;
|
|
1017
|
+
if ($[61] !== t34 || $[62] !== t38) {
|
|
1018
|
+
t39 = /* @__PURE__ */ jsxs("div", {
|
|
1019
|
+
className: "povio-canvas-workspace-popover-actions",
|
|
1020
|
+
children: [t34, t38]
|
|
1021
|
+
});
|
|
1022
|
+
$[61] = t34;
|
|
1023
|
+
$[62] = t38;
|
|
1024
|
+
$[63] = t39;
|
|
1025
|
+
} else t39 = $[63];
|
|
1026
|
+
let t40;
|
|
1027
|
+
if ($[64] !== t27 || $[65] !== t32 || $[66] !== t33 || $[67] !== t39) {
|
|
1028
|
+
t40 = /* @__PURE__ */ jsxs("form", {
|
|
1029
|
+
onSubmit: t27,
|
|
1030
|
+
children: [
|
|
1031
|
+
t32,
|
|
1032
|
+
t33,
|
|
1033
|
+
t39
|
|
1034
|
+
]
|
|
1035
|
+
});
|
|
1036
|
+
$[64] = t27;
|
|
1037
|
+
$[65] = t32;
|
|
1038
|
+
$[66] = t33;
|
|
1039
|
+
$[67] = t39;
|
|
1040
|
+
$[68] = t40;
|
|
1041
|
+
} else t40 = $[68];
|
|
1042
|
+
let t41;
|
|
1043
|
+
if ($[69] !== T1 || $[70] !== action || $[71] !== t26 || $[72] !== t40 || $[73] !== title) {
|
|
1044
|
+
t41 = /* @__PURE__ */ jsx(T1, {
|
|
1045
|
+
"aria-label": title,
|
|
1046
|
+
role: t26,
|
|
1047
|
+
children: t40
|
|
1048
|
+
}, action);
|
|
1049
|
+
$[69] = T1;
|
|
1050
|
+
$[70] = action;
|
|
1051
|
+
$[71] = t26;
|
|
1052
|
+
$[72] = t40;
|
|
1053
|
+
$[73] = title;
|
|
1054
|
+
$[74] = t41;
|
|
1055
|
+
} else t41 = $[74];
|
|
1056
|
+
let t42;
|
|
1057
|
+
if ($[75] !== T0 || $[76] !== t20 || $[77] !== t24 || $[78] !== t25 || $[79] !== t41) {
|
|
1058
|
+
t42 = /* @__PURE__ */ jsx(T0, {
|
|
1059
|
+
triggerRef: t20,
|
|
1060
|
+
placement: t21,
|
|
1061
|
+
offset: t22,
|
|
1062
|
+
className: t23,
|
|
1063
|
+
isOpen: t24,
|
|
1064
|
+
onOpenChange: t25,
|
|
1065
|
+
children: t41
|
|
1066
|
+
});
|
|
1067
|
+
$[75] = T0;
|
|
1068
|
+
$[76] = t20;
|
|
1069
|
+
$[77] = t24;
|
|
1070
|
+
$[78] = t25;
|
|
1071
|
+
$[79] = t41;
|
|
1072
|
+
$[80] = t42;
|
|
1073
|
+
} else t42 = $[80];
|
|
1074
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("fieldset", {
|
|
1075
|
+
className: "povio-canvas-workspaces",
|
|
1076
|
+
disabled,
|
|
1077
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1078
|
+
className: "povio-canvas-workspace-picker",
|
|
1079
|
+
children: [
|
|
1080
|
+
/* @__PURE__ */ jsx("div", {
|
|
1081
|
+
className: "povio-canvas-workspace-select",
|
|
1082
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
1083
|
+
label: "Workspace",
|
|
1084
|
+
hideLabel: true,
|
|
1085
|
+
size: "small",
|
|
1086
|
+
variant: "outlined",
|
|
1087
|
+
as: "default",
|
|
1088
|
+
className: "povio-canvas-workspace-input",
|
|
1089
|
+
selectionMode: "single",
|
|
1090
|
+
isClearable: false,
|
|
1091
|
+
isDisabled: disabled,
|
|
1092
|
+
renderStaticInput: false,
|
|
1093
|
+
value: t7,
|
|
1094
|
+
items: t8,
|
|
1095
|
+
onChange: t9
|
|
1096
|
+
})
|
|
1097
|
+
}),
|
|
1098
|
+
t12,
|
|
1099
|
+
t15
|
|
1100
|
+
]
|
|
1101
|
+
}), t19]
|
|
1102
|
+
}), t42] });
|
|
1103
|
+
}
|
|
1104
|
+
function _temp2(item_3) {
|
|
1105
|
+
return item_3.id;
|
|
1106
|
+
}
|
|
1107
|
+
function _temp(item_2) {
|
|
1108
|
+
return {
|
|
1109
|
+
id: item_2.id,
|
|
1110
|
+
label: item_2.name
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
const canvasStorageTokenHeader = "x-povio-canvas-token";
|
|
1114
|
+
//#endregion
|
|
1115
|
+
//#region src/app-canvas/useCanvasStorage.ts
|
|
1116
|
+
function connectionFromDocument() {
|
|
1117
|
+
if (typeof document === "undefined") return null;
|
|
1118
|
+
try {
|
|
1119
|
+
const value = JSON.parse(document.querySelector(`meta[name="povio-ui-canvas-storage"]`)?.content ?? "null");
|
|
1120
|
+
return value && typeof value.endpoint === "string" && value.endpoint.startsWith("/") && !value.endpoint.startsWith("//") && typeof value.token === "string" && typeof value.file === "string" ? value : null;
|
|
1121
|
+
} catch {
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
function localManifest(key) {
|
|
1126
|
+
try {
|
|
1127
|
+
return parseCanvasManifest(localStorage.getItem(key));
|
|
1128
|
+
} catch {
|
|
1129
|
+
return createCanvasManifest();
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
/** Repo is authoritative when connected; local storage remains an offline draft cache. */
|
|
1133
|
+
function useCanvasStorage(key, enabled = true) {
|
|
1134
|
+
const [connection] = useState(() => enabled ? connectionFromDocument() : null);
|
|
1135
|
+
const [manifest, setManifest] = useState(() => localManifest(key));
|
|
1136
|
+
const [ready, setReady] = useState(!connection);
|
|
1137
|
+
const [status, setStatus] = useState(connection ? "Loading workspace…" : "Saved in this browser");
|
|
1138
|
+
const [error, setError] = useState("");
|
|
1139
|
+
const latest = useRef(manifest);
|
|
1140
|
+
latest.current = manifest;
|
|
1141
|
+
const revision = useRef(null);
|
|
1142
|
+
const saved = useRef("");
|
|
1143
|
+
const busy = useRef(false);
|
|
1144
|
+
const paused = useRef(false);
|
|
1145
|
+
const alive = useRef(true);
|
|
1146
|
+
const loadGeneration = useRef(0);
|
|
1147
|
+
useEffect(() => {
|
|
1148
|
+
alive.current = true;
|
|
1149
|
+
return () => {
|
|
1150
|
+
alive.current = false;
|
|
1151
|
+
};
|
|
1152
|
+
}, []);
|
|
1153
|
+
const load = useCallback(async () => {
|
|
1154
|
+
if (!connection) return;
|
|
1155
|
+
const generation = ++loadGeneration.current;
|
|
1156
|
+
setReady(false);
|
|
1157
|
+
setError("");
|
|
1158
|
+
setStatus("Loading workspace…");
|
|
1159
|
+
paused.current = false;
|
|
1160
|
+
try {
|
|
1161
|
+
const response = await fetch(connection.endpoint, {
|
|
1162
|
+
headers: { [canvasStorageTokenHeader]: connection.token },
|
|
1163
|
+
cache: "no-store"
|
|
1164
|
+
});
|
|
1165
|
+
const result = await response.json();
|
|
1166
|
+
if (!response.ok) throw new Error(result.error ?? "Could not read workspace configuration.");
|
|
1167
|
+
if (!alive.current || generation !== loadGeneration.current) return;
|
|
1168
|
+
revision.current = result.revision;
|
|
1169
|
+
if (result.manifest) {
|
|
1170
|
+
const next = parseCanvasManifest(result.manifest);
|
|
1171
|
+
saved.current = JSON.stringify(next);
|
|
1172
|
+
latest.current = next;
|
|
1173
|
+
setManifest(next);
|
|
1174
|
+
} else saved.current = "";
|
|
1175
|
+
setStatus(`Saved to ${connection.file}`);
|
|
1176
|
+
setReady(true);
|
|
1177
|
+
} catch (cause) {
|
|
1178
|
+
if (!alive.current || generation !== loadGeneration.current) return;
|
|
1179
|
+
paused.current = true;
|
|
1180
|
+
setError(cause instanceof Error ? cause.message : "Could not load repository settings.");
|
|
1181
|
+
setStatus("Repository unavailable");
|
|
1182
|
+
setReady(true);
|
|
1183
|
+
}
|
|
1184
|
+
}, [connection]);
|
|
1185
|
+
useEffect(() => {
|
|
1186
|
+
load();
|
|
1187
|
+
}, [load]);
|
|
1188
|
+
const save = useCallback(async () => {
|
|
1189
|
+
if (!connection || busy.current || paused.current || !ready) return;
|
|
1190
|
+
busy.current = true;
|
|
1191
|
+
try {
|
|
1192
|
+
while (alive.current && !paused.current) {
|
|
1193
|
+
const value = latest.current;
|
|
1194
|
+
const serialized = JSON.stringify(value);
|
|
1195
|
+
if (serialized === saved.current) break;
|
|
1196
|
+
setStatus("Saving to repository…");
|
|
1197
|
+
const response_0 = await fetch(connection.endpoint, {
|
|
1198
|
+
method: "POST",
|
|
1199
|
+
headers: {
|
|
1200
|
+
"Content-Type": "application/json",
|
|
1201
|
+
[canvasStorageTokenHeader]: connection.token
|
|
1202
|
+
},
|
|
1203
|
+
body: JSON.stringify({
|
|
1204
|
+
manifest: value,
|
|
1205
|
+
revision: revision.current
|
|
1206
|
+
})
|
|
1207
|
+
});
|
|
1208
|
+
const result_0 = await response_0.json();
|
|
1209
|
+
if (!response_0.ok) throw new Error(response_0.status === 409 ? "Workspace file changed elsewhere. Export your draft, then reload repository settings." : result_0.error ?? "Could not save workspace settings.");
|
|
1210
|
+
revision.current = result_0.revision;
|
|
1211
|
+
saved.current = serialized;
|
|
1212
|
+
}
|
|
1213
|
+
if (alive.current) {
|
|
1214
|
+
setError("");
|
|
1215
|
+
setStatus(`Saved to ${connection.file}`);
|
|
1216
|
+
}
|
|
1217
|
+
} catch (cause_0) {
|
|
1218
|
+
paused.current = true;
|
|
1219
|
+
if (alive.current) {
|
|
1220
|
+
setError(cause_0 instanceof Error ? cause_0.message : "Could not save workspace settings.");
|
|
1221
|
+
setStatus("Workspace not saved to repository");
|
|
1222
|
+
}
|
|
1223
|
+
} finally {
|
|
1224
|
+
busy.current = false;
|
|
1225
|
+
}
|
|
1226
|
+
}, [connection, ready]);
|
|
1227
|
+
useEffect(() => {
|
|
1228
|
+
if (!ready) return;
|
|
1229
|
+
try {
|
|
1230
|
+
localStorage.setItem(key, JSON.stringify(manifest));
|
|
1231
|
+
} catch {
|
|
1232
|
+
if (!connection) setStatus("Browser storage unavailable — export your layout");
|
|
1233
|
+
}
|
|
1234
|
+
if (!connection || paused.current || JSON.stringify(manifest) === saved.current) return;
|
|
1235
|
+
setStatus("Saving to repository…");
|
|
1236
|
+
const timer = setTimeout(() => {
|
|
1237
|
+
save();
|
|
1238
|
+
}, 350);
|
|
1239
|
+
return () => clearTimeout(timer);
|
|
1240
|
+
}, [
|
|
1241
|
+
manifest,
|
|
1242
|
+
key,
|
|
1243
|
+
connection,
|
|
1244
|
+
ready,
|
|
1245
|
+
save
|
|
1246
|
+
]);
|
|
1247
|
+
return {
|
|
1248
|
+
manifest,
|
|
1249
|
+
setManifest,
|
|
1250
|
+
ready,
|
|
1251
|
+
status,
|
|
1252
|
+
error,
|
|
1253
|
+
repositoryFile: connection?.file,
|
|
1254
|
+
reload: load
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
330
1257
|
//#endregion
|
|
331
1258
|
//#region src/app-canvas/useFrameStartup.ts
|
|
332
1259
|
/** Bound concurrent bootstraps, without unloading any admitted page. */
|
|
@@ -406,7 +1333,7 @@ function labelOf(element) {
|
|
|
406
1333
|
return (element.getAttribute("aria-label") || element.getAttribute("alt") || (!element.children.length ? element.textContent?.trim().replace(/\s+/g, " ") : ""))?.slice(0, 48) || (element.id ? `#${element.id}` : "");
|
|
407
1334
|
}
|
|
408
1335
|
/** Only expanded branches are read and rendered; large pages do not create a second full DOM tree. */
|
|
409
|
-
function PageLayers({ frame, title, selected, onSelect }) {
|
|
1336
|
+
function PageLayers({ frame, title, selected, onSelect, onHover }) {
|
|
410
1337
|
const [root, setRoot] = useState(null);
|
|
411
1338
|
const [, refresh] = useReducer((value) => value + 1, 0);
|
|
412
1339
|
const expanded = useRef(/* @__PURE__ */ new WeakSet());
|
|
@@ -488,7 +1415,13 @@ function PageLayers({ frame, title, selected, onSelect }) {
|
|
|
488
1415
|
"aria-expanded": children.length ? open_0 : void 0,
|
|
489
1416
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
490
1417
|
className: "povio-canvas-layer-row",
|
|
491
|
-
|
|
1418
|
+
onMouseEnter: () => onHover(element_1),
|
|
1419
|
+
onMouseLeave: () => onHover(null),
|
|
1420
|
+
onFocus: () => onHover(element_1),
|
|
1421
|
+
onBlur: (event) => {
|
|
1422
|
+
if (!event.currentTarget.contains(event.relatedTarget)) onHover(null);
|
|
1423
|
+
},
|
|
1424
|
+
style: { paddingLeft: 4 + depth * 10 },
|
|
492
1425
|
children: [children.length ? /* @__PURE__ */ jsx("button", {
|
|
493
1426
|
className: "povio-canvas-layer-toggle",
|
|
494
1427
|
"aria-label": `${open_0 ? "Collapse" : "Expand"} ${element_1.localName}${label ? ` ${label}` : ""}`,
|
|
@@ -498,13 +1431,13 @@ function PageLayers({ frame, title, selected, onSelect }) {
|
|
|
498
1431
|
className: "povio-canvas-layer-select",
|
|
499
1432
|
title: `${element_1.localName}${label ? ` · ${label}` : ""}`,
|
|
500
1433
|
onClick: () => onSelect(element_1),
|
|
501
|
-
onKeyDown: (
|
|
502
|
-
if (
|
|
503
|
-
|
|
1434
|
+
onKeyDown: (event_0) => {
|
|
1435
|
+
if (event_0.key === "ArrowRight" && children.length && !open_0) {
|
|
1436
|
+
event_0.preventDefault();
|
|
504
1437
|
toggle(element_1, false);
|
|
505
1438
|
}
|
|
506
|
-
if (
|
|
507
|
-
|
|
1439
|
+
if (event_0.key === "ArrowLeft" && open_0) {
|
|
1440
|
+
event_0.preventDefault();
|
|
508
1441
|
toggle(element_1, true);
|
|
509
1442
|
}
|
|
510
1443
|
},
|
|
@@ -521,11 +1454,6 @@ function PageLayers({ frame, title, selected, onSelect }) {
|
|
|
521
1454
|
className: "povio-canvas-layers",
|
|
522
1455
|
"aria-label": `Layers for ${title}`,
|
|
523
1456
|
children: [
|
|
524
|
-
/* @__PURE__ */ jsxs("header", { children: [
|
|
525
|
-
/* @__PURE__ */ jsx(CodeXml, { size: 14 }),
|
|
526
|
-
/* @__PURE__ */ jsx("strong", { children: "Layers" }),
|
|
527
|
-
/* @__PURE__ */ jsx("span", { children: title })
|
|
528
|
-
] }),
|
|
529
1457
|
/* @__PURE__ */ jsx("div", {
|
|
530
1458
|
role: "tree",
|
|
531
1459
|
"aria-label": "HTML layers",
|
|
@@ -542,10 +1470,8 @@ function PageLayers({ frame, title, selected, onSelect }) {
|
|
|
542
1470
|
}
|
|
543
1471
|
//#endregion
|
|
544
1472
|
//#region src/app-canvas/CanvasInspector.tsx
|
|
545
|
-
const unknownToken = () => false;
|
|
546
|
-
const readOnly = () => {};
|
|
547
1473
|
/** Inspect the live iframe DOM using its own, unscaled viewport coordinates. */
|
|
548
|
-
function useCanvasInspector(enabled, generation) {
|
|
1474
|
+
function useCanvasInspector(enabled, generation, isKnown) {
|
|
549
1475
|
const [selection, setSelection] = useState(null);
|
|
550
1476
|
const [measurement, setMeasurement] = useState(null);
|
|
551
1477
|
const [pinned, setPinned] = useState(false);
|
|
@@ -632,7 +1558,7 @@ function useCanvasInspector(enabled, generation) {
|
|
|
632
1558
|
return;
|
|
633
1559
|
}
|
|
634
1560
|
const rect = element_0.getBoundingClientRect();
|
|
635
|
-
const snapshot = inspectElement(element_0,
|
|
1561
|
+
const snapshot = inspectElement(element_0, isKnown);
|
|
636
1562
|
const details = highlightKey ? getBoxHighlights(element_0, highlightKey) : null;
|
|
637
1563
|
const spacing = highlightKey ? [] : [
|
|
638
1564
|
"padding.top",
|
|
@@ -726,7 +1652,8 @@ function useCanvasInspector(enabled, generation) {
|
|
|
726
1652
|
enabled,
|
|
727
1653
|
selection,
|
|
728
1654
|
highlightKey,
|
|
729
|
-
clear
|
|
1655
|
+
clear,
|
|
1656
|
+
isKnown
|
|
730
1657
|
]);
|
|
731
1658
|
return {
|
|
732
1659
|
selection,
|
|
@@ -748,8 +1675,8 @@ function useCanvasInspector(enabled, generation) {
|
|
|
748
1675
|
};
|
|
749
1676
|
}
|
|
750
1677
|
function CanvasInspectorPanel(t0) {
|
|
751
|
-
const $ = c(
|
|
752
|
-
const { inspector, onClose } = t0;
|
|
1678
|
+
const $ = c(22);
|
|
1679
|
+
const { inspector, onClose, onSelectToken } = t0;
|
|
753
1680
|
let t1;
|
|
754
1681
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
755
1682
|
t1 = /* @__PURE__ */ jsx("strong", { children: "Inspector view" });
|
|
@@ -812,10 +1739,10 @@ function CanvasInspectorPanel(t0) {
|
|
|
812
1739
|
$[13] = t9;
|
|
813
1740
|
} else t9 = $[13];
|
|
814
1741
|
let t10;
|
|
815
|
-
if ($[14] !== inspector.highlight || $[15] !== inspector.measurement) {
|
|
1742
|
+
if ($[14] !== inspector.highlight || $[15] !== inspector.measurement || $[16] !== onSelectToken) {
|
|
816
1743
|
t10 = inspector.measurement ? /* @__PURE__ */ jsx(InspectorDetails, {
|
|
817
1744
|
snapshot: inspector.measurement.snapshot,
|
|
818
|
-
onSelect:
|
|
1745
|
+
onSelect: onSelectToken,
|
|
819
1746
|
onHighlight: inspector.highlight
|
|
820
1747
|
}) : /* @__PURE__ */ jsx("p", {
|
|
821
1748
|
className: "povio-canvas-inspect-hint",
|
|
@@ -823,10 +1750,11 @@ function CanvasInspectorPanel(t0) {
|
|
|
823
1750
|
});
|
|
824
1751
|
$[14] = inspector.highlight;
|
|
825
1752
|
$[15] = inspector.measurement;
|
|
826
|
-
$[16] =
|
|
827
|
-
|
|
1753
|
+
$[16] = onSelectToken;
|
|
1754
|
+
$[17] = t10;
|
|
1755
|
+
} else t10 = $[17];
|
|
828
1756
|
let t11;
|
|
829
|
-
if ($[
|
|
1757
|
+
if ($[18] !== t10 || $[19] !== t7 || $[20] !== t9) {
|
|
830
1758
|
t11 = /* @__PURE__ */ jsxs("aside", {
|
|
831
1759
|
className: "studio-inspector-panel povio-canvas-inspector",
|
|
832
1760
|
"aria-label": "Inspector view",
|
|
@@ -836,11 +1764,11 @@ function CanvasInspectorPanel(t0) {
|
|
|
836
1764
|
t10
|
|
837
1765
|
]
|
|
838
1766
|
});
|
|
839
|
-
$[
|
|
840
|
-
$[
|
|
841
|
-
$[
|
|
842
|
-
$[
|
|
843
|
-
} else t11 = $[
|
|
1767
|
+
$[18] = t10;
|
|
1768
|
+
$[19] = t7;
|
|
1769
|
+
$[20] = t9;
|
|
1770
|
+
$[21] = t11;
|
|
1771
|
+
} else t11 = $[21];
|
|
844
1772
|
return t11;
|
|
845
1773
|
}
|
|
846
1774
|
function CanvasInspectionOverlay(t0) {
|
|
@@ -892,6 +1820,64 @@ function CanvasInspectionOverlay(t0) {
|
|
|
892
1820
|
} else t3 = $[8];
|
|
893
1821
|
return t3;
|
|
894
1822
|
}
|
|
1823
|
+
/** Temporary layer hover never replaces the pinned inspector selection. */
|
|
1824
|
+
function CanvasLayerHighlight(t0) {
|
|
1825
|
+
const $ = c(5);
|
|
1826
|
+
const { element } = t0;
|
|
1827
|
+
const [bounds, setBounds] = useState(null);
|
|
1828
|
+
let t1;
|
|
1829
|
+
let t2;
|
|
1830
|
+
if ($[0] !== element) {
|
|
1831
|
+
t1 = () => {
|
|
1832
|
+
const owner = element.ownerDocument.defaultView;
|
|
1833
|
+
const measure = () => {
|
|
1834
|
+
if (!element.isConnected) {
|
|
1835
|
+
setBounds(null);
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
const rect = element.getBoundingClientRect();
|
|
1839
|
+
setBounds({
|
|
1840
|
+
left: rect.left,
|
|
1841
|
+
top: rect.top,
|
|
1842
|
+
width: rect.width,
|
|
1843
|
+
height: rect.height
|
|
1844
|
+
});
|
|
1845
|
+
};
|
|
1846
|
+
measure();
|
|
1847
|
+
const observer = new ResizeObserver(measure);
|
|
1848
|
+
observer.observe(element);
|
|
1849
|
+
owner?.addEventListener("scroll", measure, true);
|
|
1850
|
+
owner?.addEventListener("resize", measure);
|
|
1851
|
+
return () => {
|
|
1852
|
+
observer.disconnect();
|
|
1853
|
+
owner?.removeEventListener("scroll", measure, true);
|
|
1854
|
+
owner?.removeEventListener("resize", measure);
|
|
1855
|
+
};
|
|
1856
|
+
};
|
|
1857
|
+
t2 = [element];
|
|
1858
|
+
$[0] = element;
|
|
1859
|
+
$[1] = t1;
|
|
1860
|
+
$[2] = t2;
|
|
1861
|
+
} else {
|
|
1862
|
+
t1 = $[1];
|
|
1863
|
+
t2 = $[2];
|
|
1864
|
+
}
|
|
1865
|
+
useLayoutEffect(t1, t2);
|
|
1866
|
+
let t3;
|
|
1867
|
+
if ($[3] !== bounds) {
|
|
1868
|
+
t3 = bounds ? /* @__PURE__ */ jsx("div", {
|
|
1869
|
+
className: "povio-canvas-inspection-overlay povio-canvas-layer-highlight",
|
|
1870
|
+
"aria-hidden": "true",
|
|
1871
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1872
|
+
className: "studio-hover-outline",
|
|
1873
|
+
style: bounds
|
|
1874
|
+
})
|
|
1875
|
+
}) : null;
|
|
1876
|
+
$[3] = bounds;
|
|
1877
|
+
$[4] = t3;
|
|
1878
|
+
} else t3 = $[4];
|
|
1879
|
+
return t3;
|
|
1880
|
+
}
|
|
895
1881
|
//#endregion
|
|
896
1882
|
//#region src/app-canvas/route-model.ts
|
|
897
1883
|
function joinPath(parent, path) {
|
|
@@ -1070,68 +2056,6 @@ function validConfiguration(value) {
|
|
|
1070
2056
|
}) && !!config.config && typeof config.config === "object";
|
|
1071
2057
|
}
|
|
1072
2058
|
//#endregion
|
|
1073
|
-
//#region src/app-canvas/manifest.ts
|
|
1074
|
-
function createCanvasManifest() {
|
|
1075
|
-
return {
|
|
1076
|
-
version: 1,
|
|
1077
|
-
positions: {},
|
|
1078
|
-
examples: {},
|
|
1079
|
-
manualEdges: [],
|
|
1080
|
-
hiddenEdges: [],
|
|
1081
|
-
breakpoint: "desktop"
|
|
1082
|
-
};
|
|
1083
|
-
}
|
|
1084
|
-
function isRecord(value) {
|
|
1085
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1086
|
-
}
|
|
1087
|
-
function isJSON(value, ancestors = /* @__PURE__ */ new Set(), depth = 0) {
|
|
1088
|
-
if (value === null || typeof value === "string" || typeof value === "boolean") return true;
|
|
1089
|
-
if (typeof value === "number") return Number.isFinite(value);
|
|
1090
|
-
if (typeof value !== "object" || depth > 30 || ancestors.has(value)) return false;
|
|
1091
|
-
ancestors.add(value);
|
|
1092
|
-
const valid = Object.values(value).every((child) => isJSON(child, ancestors, depth + 1));
|
|
1093
|
-
ancestors.delete(value);
|
|
1094
|
-
return valid;
|
|
1095
|
-
}
|
|
1096
|
-
/** Sanitize either stored JSON text or an imported value, retaining valid v1 entries. */
|
|
1097
|
-
function parseCanvasManifest(input) {
|
|
1098
|
-
const fallback = createCanvasManifest();
|
|
1099
|
-
let value = input;
|
|
1100
|
-
if (typeof value === "string") try {
|
|
1101
|
-
value = JSON.parse(value);
|
|
1102
|
-
} catch {
|
|
1103
|
-
return fallback;
|
|
1104
|
-
}
|
|
1105
|
-
if (!isRecord(value) || value.version !== 1) return fallback;
|
|
1106
|
-
const positions = Object.fromEntries(Object.entries(isRecord(value.positions) ? value.positions : {}).flatMap(([breakpoint, entries]) => {
|
|
1107
|
-
if (!isRecord(entries)) return [];
|
|
1108
|
-
return [[breakpoint, Object.fromEntries(Object.entries(entries).flatMap(([id, point]) => isRecord(point) && typeof point.x === "number" && Number.isFinite(point.x) && typeof point.y === "number" && Number.isFinite(point.y) ? [[id, {
|
|
1109
|
-
x: point.x,
|
|
1110
|
-
y: point.y
|
|
1111
|
-
}]] : []))]];
|
|
1112
|
-
}));
|
|
1113
|
-
const examples = Object.fromEntries(Object.entries(isRecord(value.examples) ? value.examples : {}).flatMap(([id, example]) => {
|
|
1114
|
-
if (!isRecord(example)) return [];
|
|
1115
|
-
const clean = {};
|
|
1116
|
-
if (typeof example.title === "string") clean.title = example.title;
|
|
1117
|
-
if (isRecord(example.params)) clean.params = Object.fromEntries(Object.entries(example.params).filter((entry) => typeof entry[1] === "string"));
|
|
1118
|
-
if (isRecord(example.search)) clean.search = Object.fromEntries(Object.entries(example.search).filter(([, item]) => isJSON(item)));
|
|
1119
|
-
return [[id, clean]];
|
|
1120
|
-
}));
|
|
1121
|
-
const manualEdges = (Array.isArray(value.manualEdges) ? value.manualEdges : []).flatMap((edge) => isRecord(edge) && typeof edge.from === "string" && edge.from.length > 0 && typeof edge.to === "string" && edge.to.length > 0 ? [{
|
|
1122
|
-
from: edge.from,
|
|
1123
|
-
to: edge.to
|
|
1124
|
-
}] : []);
|
|
1125
|
-
return {
|
|
1126
|
-
version: 1,
|
|
1127
|
-
positions,
|
|
1128
|
-
examples,
|
|
1129
|
-
manualEdges: [...new Map(manualEdges.map((edge) => [JSON.stringify(edge), edge])).values()],
|
|
1130
|
-
hiddenEdges: [...new Set((Array.isArray(value.hiddenEdges) ? value.hiddenEdges : []).filter((edge) => typeof edge === "string"))],
|
|
1131
|
-
breakpoint: typeof value.breakpoint === "string" && value.breakpoint.length > 0 ? value.breakpoint : fallback.breakpoint
|
|
1132
|
-
};
|
|
1133
|
-
}
|
|
1134
|
-
//#endregion
|
|
1135
2059
|
//#region src/app-canvas/AppCanvas.tsx
|
|
1136
2060
|
const defaultCanvasBreakpoints = [
|
|
1137
2061
|
{
|
|
@@ -1155,14 +2079,9 @@ const defaultCanvasBreakpoints = [
|
|
|
1155
2079
|
];
|
|
1156
2080
|
const emptyExamples = {};
|
|
1157
2081
|
const emptyExclude = [];
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
return parseCanvasManifest(localStorage.getItem(key));
|
|
1162
|
-
} catch {
|
|
1163
|
-
return createCanvasManifest();
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
2082
|
+
/** Zoom per wheel pixel, and the largest delta one wheel event may contribute. */
|
|
2083
|
+
const ZOOM_SENSITIVITY = .006;
|
|
2084
|
+
const ZOOM_DELTA_LIMIT = 40;
|
|
1166
2085
|
const PageFrame = memo(function PageFrame(t0) {
|
|
1167
2086
|
const $ = c(16);
|
|
1168
2087
|
const { id, src, width, height, name, interact, inspect, onLoad, register } = t0;
|
|
@@ -1211,19 +2130,33 @@ const PageFrame = memo(function PageFrame(t0) {
|
|
|
1211
2130
|
return t6;
|
|
1212
2131
|
});
|
|
1213
2132
|
/** Live route artboards. The camera transforms only the canvas, never the iframe viewport width. */
|
|
1214
|
-
function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, excludePaths = emptyExclude, breakpoints = defaultCanvasBreakpoints, storageKey = "povio-app-canvas", frameUrl }) {
|
|
2133
|
+
function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, excludePaths = emptyExclude, breakpoints = defaultCanvasBreakpoints, storageKey = "povio-app-canvas", frameUrl, componentsHref, repositoryStorage = true }) {
|
|
1215
2134
|
const configuration = useUIConfiguration();
|
|
1216
|
-
const
|
|
2135
|
+
const storage = useCanvasStorage(storageKey, repositoryStorage);
|
|
2136
|
+
const { manifest, setManifest } = storage;
|
|
2137
|
+
const workspace = manifest.workspaces.find((item) => item.id === manifest.activeWorkspaceId);
|
|
1217
2138
|
const [runtime, setRuntime] = useState({});
|
|
2139
|
+
const [hoveredLayer, setHoveredLayer] = useState(null);
|
|
1218
2140
|
const [selected, setSelected] = useState(null);
|
|
1219
2141
|
const [interact, setInteract] = useState(false);
|
|
1220
2142
|
const [inspectMode, setInspectMode] = useState(false);
|
|
1221
2143
|
const [dark, setDark] = useState(false);
|
|
2144
|
+
/** The canvas shows either the app's pages or the component gallery's sections, as artboards either way. */
|
|
2145
|
+
const [content, setContent] = useState("pages");
|
|
1222
2146
|
const [mobilePanel, setMobilePanel] = useState(null);
|
|
1223
2147
|
const [query, setQuery] = useState("");
|
|
1224
2148
|
const [notice, setNotice] = useState("");
|
|
1225
2149
|
const [documentGeneration, setDocumentGeneration] = useState(0);
|
|
2150
|
+
useWorkspaceConfiguration(workspace, storage.ready, documentGeneration, setManifest);
|
|
1226
2151
|
const [reload, setReload] = useState({});
|
|
2152
|
+
const [showLayers, setShowLayers] = useState(true);
|
|
2153
|
+
useEffect(() => setHoveredLayer(null), [
|
|
2154
|
+
selected,
|
|
2155
|
+
showLayers,
|
|
2156
|
+
manifest.activeWorkspaceId,
|
|
2157
|
+
manifest.breakpoint,
|
|
2158
|
+
documentGeneration
|
|
2159
|
+
]);
|
|
1227
2160
|
const zoomOutput = useRef(null);
|
|
1228
2161
|
const importInput = useRef(null);
|
|
1229
2162
|
const viewport = useRef(null), world = useRef(null);
|
|
@@ -1236,9 +2169,12 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1236
2169
|
}), pendingCamera = useRef(null);
|
|
1237
2170
|
const pointer = useRef(null);
|
|
1238
2171
|
const cameraRevision = useRef(0);
|
|
1239
|
-
const bp = breakpoints.find((
|
|
1240
|
-
const
|
|
1241
|
-
const
|
|
2172
|
+
const bp = breakpoints.find((item_0) => item_0.id === manifest.breakpoint) ?? breakpoints[breakpoints.length - 1] ?? defaultCanvasBreakpoints[2];
|
|
2173
|
+
const isKnownToken = useCallback((name) => isEditableToken(name, configuration.defaults), [configuration.defaults]);
|
|
2174
|
+
const { hostComponents } = configuration;
|
|
2175
|
+
useEffect(() => hostComponents(), [hostComponents]);
|
|
2176
|
+
const inspector = useCanvasInspector(inspectMode, `${manifest.activeWorkspaceId}:${content}:${bp.id}:${documentGeneration}:${JSON.stringify(reload)}`, isKnownToken);
|
|
2177
|
+
const allPages = useMemo(() => discoverCanvasPages(router, {
|
|
1242
2178
|
examples: {
|
|
1243
2179
|
...examples,
|
|
1244
2180
|
...manifest.examples
|
|
@@ -1252,7 +2188,21 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1252
2188
|
exclude,
|
|
1253
2189
|
excludePaths
|
|
1254
2190
|
]);
|
|
1255
|
-
const
|
|
2191
|
+
const pageCatalog = useMemo(() => storage.ready ? allPages.filter((page) => workspace.enabledPages === null || workspace.enabledPages.includes(page.id)) : [], [
|
|
2192
|
+
allPages,
|
|
2193
|
+
workspace.enabledPages,
|
|
2194
|
+
storage.ready
|
|
2195
|
+
]);
|
|
2196
|
+
const componentCatalog = useMemo(() => componentsHref ? componentArtboards.map((group) => ({
|
|
2197
|
+
id: `components:${group.toLowerCase()}`,
|
|
2198
|
+
title: group,
|
|
2199
|
+
path: group,
|
|
2200
|
+
href: componentsHref(group),
|
|
2201
|
+
missingParams: [],
|
|
2202
|
+
kind: "page"
|
|
2203
|
+
})) : [], [componentsHref]);
|
|
2204
|
+
const catalog = content === "components" && componentCatalog.length ? componentCatalog : pageCatalog;
|
|
2205
|
+
const startupKeys = useMemo(() => new Map(catalog.filter((page_0) => page_0.href).map((page_1) => [page_1.id, `${documentGeneration}:${bp.id}:${page_1.id}:${page_1.href}:${reload[page_1.id] ?? 0}`])), [
|
|
1256
2206
|
catalog,
|
|
1257
2207
|
documentGeneration,
|
|
1258
2208
|
bp.id,
|
|
@@ -1267,18 +2217,37 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1267
2217
|
keys: startupKeys,
|
|
1268
2218
|
complete: startup.complete
|
|
1269
2219
|
};
|
|
1270
|
-
const heights = useMemo(() => Object.fromEntries(catalog.map((
|
|
2220
|
+
const heights = useMemo(() => Object.fromEntries(catalog.map((page_2) => [page_2.id, runtime[`${bp.id}:${page_2.id}:${page_2.href ?? ""}`]?.height ?? bp.height])), [
|
|
1271
2221
|
catalog,
|
|
1272
2222
|
runtime,
|
|
1273
2223
|
bp
|
|
1274
2224
|
]);
|
|
1275
|
-
const nodes = useMemo(() => layoutCanvasPages(catalog, bp.width, heights,
|
|
2225
|
+
const nodes = useMemo(() => layoutCanvasPages(catalog, bp.width, heights, workspace.positions[bp.id] ?? {}), [
|
|
1276
2226
|
catalog,
|
|
1277
2227
|
bp,
|
|
1278
2228
|
heights,
|
|
1279
|
-
|
|
2229
|
+
workspace.positions
|
|
1280
2230
|
]);
|
|
1281
2231
|
const nodeMap = useMemo(() => new Map(nodes.map((node) => [node.id, node])), [nodes]);
|
|
2232
|
+
useLayoutEffect(() => {
|
|
2233
|
+
const gesture = pointer.current;
|
|
2234
|
+
if (gesture && viewport.current?.hasPointerCapture(gesture.id)) viewport.current.releasePointerCapture(gesture.id);
|
|
2235
|
+
pointer.current = null;
|
|
2236
|
+
setSelected(null);
|
|
2237
|
+
setQuery("");
|
|
2238
|
+
camera.current = {
|
|
2239
|
+
x: 40,
|
|
2240
|
+
y: 40,
|
|
2241
|
+
zoom: .25
|
|
2242
|
+
};
|
|
2243
|
+
}, [manifest.activeWorkspaceId]);
|
|
2244
|
+
useEffect(() => {
|
|
2245
|
+
if (selected && !nodeMap.has(selected)) setSelected(null);
|
|
2246
|
+
}, [selected, nodeMap]);
|
|
2247
|
+
useEffect(() => {
|
|
2248
|
+
const valid = new Set(catalog.map((page_3) => `${bp.id}:${page_3.id}:${page_3.href ?? ""}`));
|
|
2249
|
+
setRuntime((current) => Object.keys(current).some((key_0) => !valid.has(key_0)) ? Object.fromEntries(Object.entries(current).filter(([key]) => valid.has(key))) : current);
|
|
2250
|
+
}, [catalog, bp.id]);
|
|
1282
2251
|
const latest = useRef({
|
|
1283
2252
|
configuration: configuration.active,
|
|
1284
2253
|
dark,
|
|
@@ -1300,11 +2269,18 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1300
2269
|
else frames.current.delete(id);
|
|
1301
2270
|
}, []);
|
|
1302
2271
|
const paint = useCallback(() => {
|
|
1303
|
-
if (world.current)
|
|
2272
|
+
if (world.current) {
|
|
2273
|
+
world.current.style.transform = `translate3d(${camera.current.x}px,${camera.current.y}px,0) scale(${camera.current.zoom})`;
|
|
2274
|
+
const zoom = String(camera.current.zoom);
|
|
2275
|
+
if (world.current.style.getPropertyValue("--canvas-zoom") !== zoom) world.current.style.setProperty("--canvas-zoom", zoom);
|
|
2276
|
+
}
|
|
1304
2277
|
if (zoomOutput.current) zoomOutput.current.textContent = `${Math.round(camera.current.zoom * 1e3) / 10}%`;
|
|
1305
2278
|
const canvas = viewport.current?.closest(".povio-app-canvas");
|
|
1306
2279
|
if (canvas) canvas.setAttribute("data-camera-revision", String(++cameraRevision.current));
|
|
1307
2280
|
}, []);
|
|
2281
|
+
useLayoutEffect(() => {
|
|
2282
|
+
paint();
|
|
2283
|
+
}, [manifest.activeWorkspaceId, paint]);
|
|
1308
2284
|
const schedulePaint = useCallback(() => {
|
|
1309
2285
|
if (pendingCamera.current !== null) return;
|
|
1310
2286
|
pendingCamera.current = requestAnimationFrame(() => {
|
|
@@ -1315,18 +2291,18 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1315
2291
|
const send = useCallback((id_0, type = "configuration") => {
|
|
1316
2292
|
const frame_0 = frames.current.get(id_0);
|
|
1317
2293
|
if (!frame_0?.contentWindow) return;
|
|
1318
|
-
const
|
|
2294
|
+
const current_0 = latest.current;
|
|
1319
2295
|
try {
|
|
1320
2296
|
frame_0.contentWindow.postMessage({
|
|
1321
2297
|
protocol: canvasProtocol,
|
|
1322
2298
|
id: id_0,
|
|
1323
2299
|
token,
|
|
1324
|
-
viewportHeight:
|
|
2300
|
+
viewportHeight: current_0.bp.height,
|
|
1325
2301
|
type,
|
|
1326
|
-
configuration:
|
|
2302
|
+
configuration: current_0.configuration,
|
|
1327
2303
|
revision: revision.current,
|
|
1328
|
-
dark:
|
|
1329
|
-
interact:
|
|
2304
|
+
dark: current_0.dark,
|
|
2305
|
+
interact: current_0.interact
|
|
1330
2306
|
}, new URL(frame_0.src).origin);
|
|
1331
2307
|
} catch {
|
|
1332
2308
|
setNotice("This configuration could not be sent to the page. Check for non-serializable values.");
|
|
@@ -1336,7 +2312,8 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1336
2312
|
const node_0 = nodeMap.get(id_1), view = viewport.current;
|
|
1337
2313
|
if (!node_0 || !view) return;
|
|
1338
2314
|
setSelected(id_1);
|
|
1339
|
-
|
|
2315
|
+
setShowLayers(true);
|
|
2316
|
+
camera.current.zoom = Math.min(1, Math.max(.005, (view.clientWidth - 80) / node_0.width));
|
|
1340
2317
|
camera.current.x = 40 - node_0.x * camera.current.zoom;
|
|
1341
2318
|
camera.current.y = 40 - node_0.y * camera.current.zoom;
|
|
1342
2319
|
paint();
|
|
@@ -1351,18 +2328,18 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1351
2328
|
batch = 0;
|
|
1352
2329
|
const changes = Array.from(queue);
|
|
1353
2330
|
queue.clear();
|
|
1354
|
-
setRuntime((
|
|
1355
|
-
const next = { ...
|
|
2331
|
+
setRuntime((current_1) => {
|
|
2332
|
+
const next = { ...current_1 };
|
|
1356
2333
|
let changed = false;
|
|
1357
|
-
for (const [
|
|
1358
|
-
if (frames.current.get(
|
|
1359
|
-
next[
|
|
1360
|
-
...next[
|
|
1361
|
-
...
|
|
2334
|
+
for (const [key_1, item_1] of changes) {
|
|
2335
|
+
if (frames.current.get(item_1.id) !== item_1.frame || item_1.frame.contentWindow !== item_1.source) continue;
|
|
2336
|
+
next[key_1] = {
|
|
2337
|
+
...next[key_1],
|
|
2338
|
+
...item_1.change
|
|
1362
2339
|
};
|
|
1363
2340
|
changed = true;
|
|
1364
2341
|
}
|
|
1365
|
-
return changed ? next :
|
|
2342
|
+
return changed ? next : current_1;
|
|
1366
2343
|
});
|
|
1367
2344
|
};
|
|
1368
2345
|
const receive = (event) => {
|
|
@@ -1370,7 +2347,7 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1370
2347
|
if (packet?.protocol !== "povio-app-canvas-v1" || packet.token !== token || typeof packet.id !== "string") return;
|
|
1371
2348
|
const frame_1 = frames.current.get(packet.id);
|
|
1372
2349
|
if (!frame_1 || event.source !== frame_1.contentWindow || event.origin !== new URL(frame_1.src).origin) return;
|
|
1373
|
-
const
|
|
2350
|
+
const key_2 = `${latest.current.bp.id}:${packet.id}:${latest.current.catalog.find((page_4) => page_4.id === packet.id)?.href ?? ""}`;
|
|
1374
2351
|
let change = {};
|
|
1375
2352
|
if (packet.type === "ready") {
|
|
1376
2353
|
startupRef.current.complete(startupRef.current.keys.get(packet.id));
|
|
@@ -1392,9 +2369,9 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1392
2369
|
return;
|
|
1393
2370
|
}
|
|
1394
2371
|
if (!Object.keys(change).length) return;
|
|
1395
|
-
const pending = queue.get(
|
|
2372
|
+
const pending = queue.get(key_2);
|
|
1396
2373
|
const previous = pending?.frame === frame_1 && pending.source === event.source ? pending.change : {};
|
|
1397
|
-
queue.set(
|
|
2374
|
+
queue.set(key_2, {
|
|
1398
2375
|
id: packet.id,
|
|
1399
2376
|
frame: frame_1,
|
|
1400
2377
|
source: event.source,
|
|
@@ -1429,25 +2406,20 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1429
2406
|
useEffect(() => {
|
|
1430
2407
|
for (const id_3 of frames.current.keys()) send(id_3, "mode");
|
|
1431
2408
|
}, [interact, send]);
|
|
1432
|
-
useEffect(() => {
|
|
1433
|
-
try {
|
|
1434
|
-
localStorage.setItem(storageKey, JSON.stringify(manifest));
|
|
1435
|
-
} catch {
|
|
1436
|
-
setNotice("Browser storage is unavailable; use Export layout to save this canvas.");
|
|
1437
|
-
}
|
|
1438
|
-
}, [manifest, storageKey]);
|
|
1439
2409
|
useEffect(() => {
|
|
1440
2410
|
paint();
|
|
1441
2411
|
const element = viewport.current;
|
|
1442
2412
|
if (!element) return;
|
|
1443
2413
|
const wheel = (event_0) => {
|
|
1444
2414
|
event_0.preventDefault();
|
|
2415
|
+
if (pointer.current) return;
|
|
1445
2416
|
if (event_0.ctrlKey || event_0.metaKey) {
|
|
1446
2417
|
const box = element.getBoundingClientRect();
|
|
1447
2418
|
const x = event_0.clientX - box.left, y = event_0.clientY - box.top;
|
|
1448
2419
|
const previous_0 = camera.current.zoom;
|
|
1449
2420
|
const unit = event_0.deltaMode === 1 ? 16 : event_0.deltaMode === 2 ? element.clientHeight : 1;
|
|
1450
|
-
const
|
|
2421
|
+
const delta = Math.max(-40, Math.min(ZOOM_DELTA_LIMIT, event_0.deltaY * unit));
|
|
2422
|
+
const next_0 = Math.max(.005, Math.min(2, previous_0 * Math.exp(-delta * ZOOM_SENSITIVITY)));
|
|
1451
2423
|
camera.current.x = x - (x - camera.current.x) * next_0 / previous_0;
|
|
1452
2424
|
camera.current.y = y - (y - camera.current.y) * next_0 / previous_0;
|
|
1453
2425
|
camera.current.zoom = next_0;
|
|
@@ -1457,9 +2429,14 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1457
2429
|
}
|
|
1458
2430
|
schedulePaint();
|
|
1459
2431
|
};
|
|
2432
|
+
const unscroll = () => {
|
|
2433
|
+
if (element.scrollTop || element.scrollLeft) element.scrollTo(0, 0);
|
|
2434
|
+
};
|
|
1460
2435
|
element.addEventListener("wheel", wheel, { passive: false });
|
|
2436
|
+
element.addEventListener("scroll", unscroll);
|
|
1461
2437
|
return () => {
|
|
1462
2438
|
element.removeEventListener("wheel", wheel);
|
|
2439
|
+
element.removeEventListener("scroll", unscroll);
|
|
1463
2440
|
if (pendingCamera.current !== null) cancelAnimationFrame(pendingCamera.current);
|
|
1464
2441
|
pendingCamera.current = null;
|
|
1465
2442
|
};
|
|
@@ -1473,13 +2450,22 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1473
2450
|
camera.current.y = 40 - top * camera.current.zoom;
|
|
1474
2451
|
paint();
|
|
1475
2452
|
};
|
|
2453
|
+
const fitRef = useRef(fit);
|
|
2454
|
+
fitRef.current = fit;
|
|
2455
|
+
const switchContent = (next_1) => {
|
|
2456
|
+
if (next_1 === content) return;
|
|
2457
|
+
setContent(next_1);
|
|
2458
|
+
setSelected(null);
|
|
2459
|
+
setQuery("");
|
|
2460
|
+
requestAnimationFrame(() => fitRef.current());
|
|
2461
|
+
};
|
|
1476
2462
|
const zoomTo = (value) => {
|
|
1477
2463
|
const view_0 = viewport.current;
|
|
1478
2464
|
if (!view_0) return;
|
|
1479
|
-
const previous_1 = camera.current.zoom,
|
|
1480
|
-
camera.current.x = view_0.clientWidth / 2 - (view_0.clientWidth / 2 - camera.current.x) *
|
|
1481
|
-
camera.current.y = view_0.clientHeight / 2 - (view_0.clientHeight / 2 - camera.current.y) *
|
|
1482
|
-
camera.current.zoom =
|
|
2465
|
+
const previous_1 = camera.current.zoom, next_2 = Math.max(.005, Math.min(2, value));
|
|
2466
|
+
camera.current.x = view_0.clientWidth / 2 - (view_0.clientWidth / 2 - camera.current.x) * next_2 / previous_1;
|
|
2467
|
+
camera.current.y = view_0.clientHeight / 2 - (view_0.clientHeight / 2 - camera.current.y) * next_2 / previous_1;
|
|
2468
|
+
camera.current.zoom = next_2;
|
|
1483
2469
|
paint();
|
|
1484
2470
|
};
|
|
1485
2471
|
const stepZoom = (direction) => {
|
|
@@ -1496,58 +2482,74 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1496
2482
|
1.5,
|
|
1497
2483
|
2
|
|
1498
2484
|
];
|
|
1499
|
-
const
|
|
1500
|
-
const
|
|
1501
|
-
if (
|
|
2485
|
+
const current_2 = camera.current.zoom;
|
|
2486
|
+
const next_3 = direction === 1 ? stops.find((value_0) => value_0 > current_2 + 1e-4) : [...stops].reverse().find((value_1) => value_1 < current_2 - 1e-4);
|
|
2487
|
+
if (next_3 !== void 0) zoomTo(next_3);
|
|
1502
2488
|
};
|
|
1503
2489
|
const startPan = (event_1) => {
|
|
1504
2490
|
if (inspectMode && event_1.target.closest(".povio-canvas-frame-cover")) return;
|
|
1505
2491
|
if (event_1.button !== 0 || event_1.target.closest("button:not(.povio-canvas-frame-cover),input,select,.povio-canvas-node-header")) return;
|
|
2492
|
+
event_1.preventDefault();
|
|
1506
2493
|
event_1.currentTarget.setPointerCapture(event_1.pointerId);
|
|
1507
2494
|
pointer.current = {
|
|
1508
2495
|
id: event_1.pointerId,
|
|
1509
2496
|
x: event_1.clientX,
|
|
1510
2497
|
y: event_1.clientY,
|
|
2498
|
+
lastX: event_1.clientX,
|
|
2499
|
+
lastY: event_1.clientY,
|
|
1511
2500
|
startX: camera.current.x,
|
|
1512
2501
|
startY: camera.current.y
|
|
1513
2502
|
};
|
|
1514
2503
|
};
|
|
1515
2504
|
const move = (event_2) => {
|
|
1516
|
-
const
|
|
1517
|
-
if (!
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
2505
|
+
const current_3 = pointer.current;
|
|
2506
|
+
if (!current_3 || current_3.id !== event_2.pointerId) return;
|
|
2507
|
+
if (event_2.buttons === 0) {
|
|
2508
|
+
end(event_2, true);
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2511
|
+
current_3.lastX = event_2.clientX;
|
|
2512
|
+
current_3.lastY = event_2.clientY;
|
|
2513
|
+
const dx = event_2.clientX - current_3.x, dy = event_2.clientY - current_3.y;
|
|
2514
|
+
if (current_3.node) {
|
|
2515
|
+
const element_0 = world.current?.querySelector(`[data-node-index="${nodes.findIndex((n_3) => n_3.id === current_3.node)}"]`);
|
|
1521
2516
|
if (element_0) {
|
|
1522
|
-
element_0.style.left = `${
|
|
1523
|
-
element_0.style.top = `${
|
|
2517
|
+
element_0.style.left = `${current_3.nodeX + dx / camera.current.zoom}px`;
|
|
2518
|
+
element_0.style.top = `${current_3.nodeY + dy / camera.current.zoom}px`;
|
|
1524
2519
|
}
|
|
1525
2520
|
} else {
|
|
1526
|
-
camera.current.x =
|
|
1527
|
-
camera.current.y =
|
|
2521
|
+
camera.current.x = current_3.startX + dx;
|
|
2522
|
+
camera.current.y = current_3.startY + dy;
|
|
1528
2523
|
schedulePaint();
|
|
1529
2524
|
}
|
|
1530
2525
|
};
|
|
1531
|
-
const end = (event_3) => {
|
|
1532
|
-
const
|
|
1533
|
-
if (!
|
|
1534
|
-
|
|
2526
|
+
const end = (event_3, useLastPosition = false) => {
|
|
2527
|
+
const current_4 = pointer.current;
|
|
2528
|
+
if (!current_4 || current_4.id !== event_3.pointerId) return;
|
|
2529
|
+
pointer.current = null;
|
|
2530
|
+
if (current_4.node) {
|
|
1535
2531
|
const position = {
|
|
1536
|
-
x:
|
|
1537
|
-
y:
|
|
2532
|
+
x: current_4.nodeX + ((useLastPosition ? current_4.lastX : event_3.clientX) - current_4.x) / camera.current.zoom,
|
|
2533
|
+
y: current_4.nodeY + ((useLastPosition ? current_4.lastY : event_3.clientY) - current_4.y) / camera.current.zoom
|
|
1538
2534
|
};
|
|
1539
2535
|
setManifest((m) => ({
|
|
1540
2536
|
...m,
|
|
1541
|
-
|
|
1542
|
-
...
|
|
1543
|
-
|
|
1544
|
-
...
|
|
1545
|
-
[
|
|
2537
|
+
workspaces: m.workspaces.map((item_2) => item_2.id === m.activeWorkspaceId ? {
|
|
2538
|
+
...item_2,
|
|
2539
|
+
positions: {
|
|
2540
|
+
...item_2.positions,
|
|
2541
|
+
[bp.id]: {
|
|
2542
|
+
...item_2.positions[bp.id],
|
|
2543
|
+
...Object.fromEntries(nodes.map((node_1) => [node_1.id, {
|
|
2544
|
+
x: node_1.x,
|
|
2545
|
+
y: node_1.y
|
|
2546
|
+
}])),
|
|
2547
|
+
[current_4.node]: position
|
|
2548
|
+
}
|
|
1546
2549
|
}
|
|
1547
|
-
}
|
|
2550
|
+
} : item_2)
|
|
1548
2551
|
}));
|
|
1549
2552
|
}
|
|
1550
|
-
pointer.current = null;
|
|
1551
2553
|
if (event_3.currentTarget.hasPointerCapture(event_3.pointerId)) event_3.currentTarget.releasePointerCapture(event_3.pointerId);
|
|
1552
2554
|
};
|
|
1553
2555
|
const onLoad = useCallback((id_4, frame_3) => {
|
|
@@ -1557,16 +2559,16 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1557
2559
|
send(id_4, "mode");
|
|
1558
2560
|
}, [send]);
|
|
1559
2561
|
useEffect(() => {
|
|
1560
|
-
const timer = setTimeout(() => setRuntime((
|
|
1561
|
-
const
|
|
1562
|
-
for (const
|
|
1563
|
-
const
|
|
1564
|
-
if (
|
|
1565
|
-
...
|
|
2562
|
+
const timer = setTimeout(() => setRuntime((current_5) => {
|
|
2563
|
+
const next_4 = { ...current_5 };
|
|
2564
|
+
for (const page_5 of latest.current.catalog) {
|
|
2565
|
+
const key_3 = `${latest.current.bp.id}:${page_5.id}:${page_5.href ?? ""}`;
|
|
2566
|
+
if (page_5.href && frames.current.has(page_5.id) && !next_4[key_3]?.ready) next_4[key_3] = {
|
|
2567
|
+
...next_4[key_3],
|
|
1566
2568
|
timedOut: true
|
|
1567
2569
|
};
|
|
1568
2570
|
}
|
|
1569
|
-
return
|
|
2571
|
+
return next_4;
|
|
1570
2572
|
}), 15e3);
|
|
1571
2573
|
return () => clearTimeout(timer);
|
|
1572
2574
|
}, [
|
|
@@ -1606,13 +2608,13 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1606
2608
|
if (!file) return;
|
|
1607
2609
|
try {
|
|
1608
2610
|
const raw = JSON.parse(await file.text());
|
|
1609
|
-
if (raw?.version !== 1) throw new Error("version");
|
|
2611
|
+
if (raw?.version !== 1 && raw?.version !== 2) throw new Error("version");
|
|
1610
2612
|
setManifest(parseCanvasManifest(raw));
|
|
1611
2613
|
setRuntime({});
|
|
1612
2614
|
setDocumentGeneration((value_2) => value_2 + 1);
|
|
1613
2615
|
setNotice("Layout imported.");
|
|
1614
2616
|
} catch {
|
|
1615
|
-
setNotice("Choose a valid
|
|
2617
|
+
setNotice("Choose a valid canvas workspace JSON file.");
|
|
1616
2618
|
}
|
|
1617
2619
|
}
|
|
1618
2620
|
}),
|
|
@@ -1623,11 +2625,30 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1623
2625
|
className: "povio-canvas-catalog",
|
|
1624
2626
|
"aria-label": "Page catalog",
|
|
1625
2627
|
children: [
|
|
2628
|
+
/* @__PURE__ */ jsx(WorkspaceControls, {
|
|
2629
|
+
manifest,
|
|
2630
|
+
setManifest,
|
|
2631
|
+
pages: allPages,
|
|
2632
|
+
disabled: !storage.ready
|
|
2633
|
+
}),
|
|
1626
2634
|
/* @__PURE__ */ jsxs("div", {
|
|
1627
|
-
className: "povio-canvas-brand",
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
2635
|
+
className: "povio-canvas-brand povio-canvas-content-switch",
|
|
2636
|
+
role: "group",
|
|
2637
|
+
"aria-label": "Canvas content",
|
|
2638
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
2639
|
+
"aria-pressed": content === "pages",
|
|
2640
|
+
onClick: () => switchContent("pages"),
|
|
2641
|
+
children: ["Pages", /* @__PURE__ */ jsx("span", {
|
|
2642
|
+
className: "povio-canvas-page-count",
|
|
2643
|
+
children: pageCatalog.length
|
|
2644
|
+
})]
|
|
2645
|
+
}), !!componentCatalog.length && /* @__PURE__ */ jsxs("button", {
|
|
2646
|
+
"aria-pressed": content === "components",
|
|
2647
|
+
onClick: () => switchContent("components"),
|
|
2648
|
+
children: ["Components", /* @__PURE__ */ jsx("span", {
|
|
2649
|
+
className: "povio-canvas-page-count",
|
|
2650
|
+
children: componentCatalog.length
|
|
2651
|
+
})]
|
|
1631
2652
|
})]
|
|
1632
2653
|
}),
|
|
1633
2654
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -1635,8 +2656,8 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1635
2656
|
children: [
|
|
1636
2657
|
/* @__PURE__ */ jsx(Search, { size: 14 }),
|
|
1637
2658
|
/* @__PURE__ */ jsx("input", {
|
|
1638
|
-
"aria-label": "Find page",
|
|
1639
|
-
placeholder: "Find page…",
|
|
2659
|
+
"aria-label": content === "components" ? "Find component section" : "Find page",
|
|
2660
|
+
placeholder: content === "components" ? "Find section…" : "Find page…",
|
|
1640
2661
|
value: query,
|
|
1641
2662
|
onChange: (event_5) => setQuery(event_5.target.value)
|
|
1642
2663
|
}),
|
|
@@ -1648,37 +2669,49 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1648
2669
|
})
|
|
1649
2670
|
]
|
|
1650
2671
|
}),
|
|
1651
|
-
/* @__PURE__ */
|
|
2672
|
+
/* @__PURE__ */ jsx("div", {
|
|
1652
2673
|
className: "povio-canvas-page-list",
|
|
1653
|
-
children:
|
|
1654
|
-
"
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
2674
|
+
children: nodes.filter((node_2) => `${node_2.title} ${node_2.path}`.toLowerCase().includes(query.toLowerCase())).map((node_3) => /* @__PURE__ */ jsxs("div", {
|
|
2675
|
+
className: "povio-canvas-page-entry",
|
|
2676
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
2677
|
+
"aria-expanded": node_3.href ? selected === node_3.id && showLayers : void 0,
|
|
2678
|
+
"aria-pressed": selected === node_3.id,
|
|
2679
|
+
onClick: () => {
|
|
2680
|
+
if (selected === node_3.id && showLayers) setShowLayers(false);
|
|
2681
|
+
else focusPage(node_3.id);
|
|
2682
|
+
},
|
|
2683
|
+
children: [node_3.href ? selected === node_3.id && showLayers ? /* @__PURE__ */ jsx(ChevronDown, { size: 12 }) : /* @__PURE__ */ jsx(ChevronRight, { size: 12 }) : /* @__PURE__ */ jsx(Frame, { size: 15 }), /* @__PURE__ */ jsxs("span", {
|
|
2684
|
+
className: "povio-canvas-page-label",
|
|
2685
|
+
children: [/* @__PURE__ */ jsx("strong", { children: node_3.title }), node_3.kind === "unresolved" && /* @__PURE__ */ jsx("small", { children: "Needs parameters" })]
|
|
2686
|
+
})]
|
|
2687
|
+
}), showLayers && selected === node_3.id && node_3.href && /* @__PURE__ */ jsx("div", {
|
|
2688
|
+
className: "povio-canvas-inline-layers",
|
|
2689
|
+
children: /* @__PURE__ */ jsx(PageLayers, {
|
|
2690
|
+
frame: frames.current.get(selected) ?? null,
|
|
2691
|
+
title: nodeMap.get(selected).title,
|
|
2692
|
+
selected: inspector.selection?.pageId === selected ? inspector.selection.element : void 0,
|
|
2693
|
+
onHover: (element_1) => setHoveredLayer(element_1 ? {
|
|
2694
|
+
pageId: node_3.id,
|
|
2695
|
+
element: element_1
|
|
2696
|
+
} : null),
|
|
2697
|
+
onSelect: (element_2) => {
|
|
2698
|
+
setInteract(false);
|
|
2699
|
+
setInspectMode(true);
|
|
2700
|
+
inspector.selectElement(selected, element_2);
|
|
2701
|
+
setMobilePanel(null);
|
|
2702
|
+
requestAnimationFrame(() => {
|
|
2703
|
+
const node_4 = nodeMap.get(selected), view_1 = viewport.current;
|
|
2704
|
+
if (!node_4 || !view_1 || !element_2.isConnected) return;
|
|
2705
|
+
const rect = element_2.getBoundingClientRect();
|
|
2706
|
+
camera.current.zoom = Math.min(camera.current.zoom, Math.max(.005, (view_1.clientWidth - 80) / node_4.width));
|
|
2707
|
+
camera.current.x = 40 - node_4.x * camera.current.zoom;
|
|
2708
|
+
camera.current.y = view_1.clientHeight / 2 - (node_4.y + 48 + rect.top + rect.height / 2) * camera.current.zoom;
|
|
2709
|
+
paint();
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2712
|
+
}, `${bp.id}:${documentGeneration}:${reload[selected] ?? 0}:${selected}:${nodeMap.get(selected)?.href}`)
|
|
1662
2713
|
})]
|
|
1663
|
-
},
|
|
1664
|
-
frame: frames.current.get(selected) ?? null,
|
|
1665
|
-
title: nodeMap.get(selected).title,
|
|
1666
|
-
selected: inspector.selection?.pageId === selected ? inspector.selection.element : void 0,
|
|
1667
|
-
onSelect: (element_1) => {
|
|
1668
|
-
setInteract(false);
|
|
1669
|
-
setInspectMode(true);
|
|
1670
|
-
inspector.selectElement(selected, element_1);
|
|
1671
|
-
setMobilePanel(null);
|
|
1672
|
-
requestAnimationFrame(() => {
|
|
1673
|
-
const node_3 = nodeMap.get(selected), view_1 = viewport.current;
|
|
1674
|
-
if (!node_3 || !view_1 || !element_1.isConnected) return;
|
|
1675
|
-
const rect = element_1.getBoundingClientRect();
|
|
1676
|
-
camera.current.x = view_1.clientWidth / 2 - (node_3.x + rect.left + rect.width / 2) * camera.current.zoom;
|
|
1677
|
-
camera.current.y = view_1.clientHeight / 2 - (node_3.y + 48 + rect.top + rect.height / 2) * camera.current.zoom;
|
|
1678
|
-
paint();
|
|
1679
|
-
});
|
|
1680
|
-
}
|
|
1681
|
-
}, `${bp.id}:${documentGeneration}:${reload[selected] ?? 0}:${selected}:${nodeMap.get(selected)?.href}`)]
|
|
2714
|
+
}, node_3.id))
|
|
1682
2715
|
}),
|
|
1683
2716
|
/* @__PURE__ */ jsxs("div", {
|
|
1684
2717
|
className: "povio-canvas-sidebar-actions",
|
|
@@ -1705,10 +2738,28 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1705
2738
|
ready,
|
|
1706
2739
|
"/",
|
|
1707
2740
|
nodes.length,
|
|
1708
|
-
"
|
|
2741
|
+
" ",
|
|
2742
|
+
content === "components" ? "sections" : "pages",
|
|
2743
|
+
" ready"
|
|
1709
2744
|
]
|
|
1710
2745
|
})
|
|
1711
2746
|
]
|
|
2747
|
+
}),
|
|
2748
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2749
|
+
className: "povio-canvas-storage-status",
|
|
2750
|
+
role: "status",
|
|
2751
|
+
children: [
|
|
2752
|
+
storage.status,
|
|
2753
|
+
/* @__PURE__ */ jsx(SaveCanvasTheme, {}),
|
|
2754
|
+
storage.error && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("p", { children: storage.error }), /* @__PURE__ */ jsx("button", {
|
|
2755
|
+
onClick: () => {
|
|
2756
|
+
setRuntime({});
|
|
2757
|
+
setDocumentGeneration((value_3) => value_3 + 1);
|
|
2758
|
+
storage.reload();
|
|
2759
|
+
},
|
|
2760
|
+
children: "Reload repository settings"
|
|
2761
|
+
})] })
|
|
2762
|
+
]
|
|
1712
2763
|
})
|
|
1713
2764
|
]
|
|
1714
2765
|
}),
|
|
@@ -1724,18 +2775,8 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1724
2775
|
onPointerDown: startPan,
|
|
1725
2776
|
onPointerMove: move,
|
|
1726
2777
|
onPointerUp: end,
|
|
1727
|
-
onPointerCancel: (event_7) =>
|
|
1728
|
-
|
|
1729
|
-
if (current_5?.node) {
|
|
1730
|
-
const element_2 = world.current?.querySelector(`[data-node-index="${nodes.findIndex((node_4) => node_4.id === current_5.node)}"]`);
|
|
1731
|
-
if (element_2) {
|
|
1732
|
-
element_2.style.left = `${current_5.nodeX}px`;
|
|
1733
|
-
element_2.style.top = `${current_5.nodeY}px`;
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
pointer.current = null;
|
|
1737
|
-
if (event_7.currentTarget.hasPointerCapture(event_7.pointerId)) event_7.currentTarget.releasePointerCapture(event_7.pointerId);
|
|
1738
|
-
},
|
|
2778
|
+
onPointerCancel: (event_7) => end(event_7, true),
|
|
2779
|
+
onLostPointerCapture: (event_8) => end(event_8, true),
|
|
1739
2780
|
children: [
|
|
1740
2781
|
/* @__PURE__ */ jsx("div", {
|
|
1741
2782
|
className: "povio-canvas-mobile-tools",
|
|
@@ -1781,14 +2822,18 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1781
2822
|
children: [
|
|
1782
2823
|
/* @__PURE__ */ jsxs("header", {
|
|
1783
2824
|
className: "povio-canvas-node-header",
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
2825
|
+
onDragStart: (event_9) => event_9.preventDefault(),
|
|
2826
|
+
onPointerDown: (event_10) => {
|
|
2827
|
+
if (event_10.button !== 0 || event_10.target.closest("button")) return;
|
|
2828
|
+
event_10.preventDefault();
|
|
2829
|
+
event_10.stopPropagation();
|
|
2830
|
+
viewport.current?.setPointerCapture(event_10.pointerId);
|
|
1788
2831
|
pointer.current = {
|
|
1789
|
-
id:
|
|
1790
|
-
x:
|
|
1791
|
-
y:
|
|
2832
|
+
id: event_10.pointerId,
|
|
2833
|
+
x: event_10.clientX,
|
|
2834
|
+
y: event_10.clientY,
|
|
2835
|
+
lastX: event_10.clientX,
|
|
2836
|
+
lastY: event_10.clientY,
|
|
1792
2837
|
startX: 0,
|
|
1793
2838
|
startY: 0,
|
|
1794
2839
|
node: node_5.id,
|
|
@@ -1827,12 +2872,12 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1827
2872
|
}),
|
|
1828
2873
|
!node_5.href ? /* @__PURE__ */ jsxs("form", {
|
|
1829
2874
|
className: "povio-canvas-unresolved",
|
|
1830
|
-
onSubmit: (
|
|
1831
|
-
|
|
1832
|
-
const form = new FormData(
|
|
1833
|
-
const enteredParams = Object.fromEntries(node_5.missingParams.map((
|
|
1834
|
-
const
|
|
1835
|
-
return [
|
|
2875
|
+
onSubmit: (event_11) => {
|
|
2876
|
+
event_11.preventDefault();
|
|
2877
|
+
const form = new FormData(event_11.currentTarget);
|
|
2878
|
+
const enteredParams = Object.fromEntries(node_5.missingParams.map((key_4) => {
|
|
2879
|
+
const value_4 = form.get(key_4);
|
|
2880
|
+
return [key_4, typeof value_4 === "string" ? value_4 : ""];
|
|
1836
2881
|
}));
|
|
1837
2882
|
setManifest((m_0) => ({
|
|
1838
2883
|
...m_0,
|
|
@@ -1853,10 +2898,10 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1853
2898
|
children: [
|
|
1854
2899
|
/* @__PURE__ */ jsx("strong", { children: "Route needs parameters" }),
|
|
1855
2900
|
/* @__PURE__ */ jsx("code", { children: node_5.path }),
|
|
1856
|
-
node_5.missingParams.map((
|
|
1857
|
-
name:
|
|
2901
|
+
node_5.missingParams.map((key_5) => /* @__PURE__ */ jsxs("label", { children: [key_5, /* @__PURE__ */ jsx("input", {
|
|
2902
|
+
name: key_5,
|
|
1858
2903
|
required: true
|
|
1859
|
-
})] },
|
|
2904
|
+
})] }, key_5)),
|
|
1860
2905
|
/* @__PURE__ */ jsx("button", { children: "Render page" })
|
|
1861
2906
|
]
|
|
1862
2907
|
}) : originError ? /* @__PURE__ */ jsx("p", {
|
|
@@ -1887,25 +2932,26 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1887
2932
|
className: "povio-canvas-frame-cover",
|
|
1888
2933
|
tabIndex: 0,
|
|
1889
2934
|
"aria-label": `Select ${node_5.title}`,
|
|
1890
|
-
onKeyDown: (
|
|
1891
|
-
if (
|
|
1892
|
-
|
|
2935
|
+
onKeyDown: (event_12) => {
|
|
2936
|
+
if (event_12.key === "Enter" || event_12.key === " ") {
|
|
2937
|
+
event_12.preventDefault();
|
|
1893
2938
|
setSelected(node_5.id);
|
|
1894
2939
|
}
|
|
1895
2940
|
},
|
|
1896
|
-
onPointerMove: (
|
|
2941
|
+
onPointerMove: (event_13) => {
|
|
1897
2942
|
const frame_4 = frames.current.get(node_5.id);
|
|
1898
|
-
if (frame_4) inspector.hover(node_5.id, frame_4,
|
|
2943
|
+
if (frame_4) inspector.hover(node_5.id, frame_4, event_13.clientX, event_13.clientY);
|
|
1899
2944
|
},
|
|
1900
|
-
onPointerDown: (
|
|
2945
|
+
onPointerDown: (event_14) => {
|
|
1901
2946
|
setSelected(node_5.id);
|
|
1902
2947
|
if (inspectMode) {
|
|
1903
2948
|
const frame_5 = frames.current.get(node_5.id);
|
|
1904
|
-
if (frame_5) inspector.select(node_5.id, frame_5,
|
|
2949
|
+
if (frame_5) inspector.select(node_5.id, frame_5, event_14.clientX, event_14.clientY);
|
|
1905
2950
|
}
|
|
1906
2951
|
},
|
|
1907
2952
|
onClick: () => setSelected(node_5.id)
|
|
1908
2953
|
}),
|
|
2954
|
+
hoveredLayer?.pageId === node_5.id && /* @__PURE__ */ jsx(CanvasLayerHighlight, { element: hoveredLayer.element }),
|
|
1909
2955
|
inspectMode && inspector.selection?.pageId === node_5.id && inspector.measurement && /* @__PURE__ */ jsx(CanvasInspectionOverlay, {
|
|
1910
2956
|
measurement: inspector.measurement,
|
|
1911
2957
|
width: node_5.width
|
|
@@ -1923,6 +2969,10 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1923
2969
|
}, node_5.id);
|
|
1924
2970
|
})
|
|
1925
2971
|
}),
|
|
2972
|
+
!nodes.length && /* @__PURE__ */ jsx("div", {
|
|
2973
|
+
className: "povio-canvas-empty",
|
|
2974
|
+
children: storage.ready ? "Enable pages in this workspace to start arranging your canvas." : "Loading workspace…"
|
|
2975
|
+
}),
|
|
1926
2976
|
/* @__PURE__ */ jsxs("div", {
|
|
1927
2977
|
className: "povio-canvas-tool-dock",
|
|
1928
2978
|
children: [
|
|
@@ -1968,10 +3018,13 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1968
3018
|
"aria-label": "Auto layout",
|
|
1969
3019
|
onClick: () => setManifest((m_1) => ({
|
|
1970
3020
|
...m_1,
|
|
1971
|
-
|
|
1972
|
-
...
|
|
1973
|
-
|
|
1974
|
-
|
|
3021
|
+
workspaces: m_1.workspaces.map((item_3) => item_3.id === m_1.activeWorkspaceId ? {
|
|
3022
|
+
...item_3,
|
|
3023
|
+
positions: {
|
|
3024
|
+
...item_3.positions,
|
|
3025
|
+
[bp.id]: {}
|
|
3026
|
+
}
|
|
3027
|
+
} : item_3)
|
|
1975
3028
|
})),
|
|
1976
3029
|
children: [/* @__PURE__ */ jsx(PanelsTopLeft, { size: 17 }), /* @__PURE__ */ jsx("span", { children: "Auto layout" })]
|
|
1977
3030
|
})
|
|
@@ -1995,29 +3048,33 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
1995
3048
|
title: "Toggle page theme",
|
|
1996
3049
|
children: dark ? /* @__PURE__ */ jsx(Moon, { size: 16 }) : /* @__PURE__ */ jsx(Sun, { size: 16 })
|
|
1997
3050
|
}),
|
|
1998
|
-
/* @__PURE__ */
|
|
1999
|
-
className: "povio-canvas-breakpoint",
|
|
2000
|
-
children:
|
|
2001
|
-
|
|
3051
|
+
/* @__PURE__ */ jsx("div", {
|
|
3052
|
+
className: "povio-canvas-breakpoint povio-canvas-workspace-select",
|
|
3053
|
+
children: /* @__PURE__ */ jsx(Select, {
|
|
3054
|
+
label: "Canvas breakpoint",
|
|
3055
|
+
hideLabel: true,
|
|
3056
|
+
size: "small",
|
|
3057
|
+
variant: "outlined",
|
|
3058
|
+
as: "default",
|
|
3059
|
+
className: "povio-canvas-workspace-input",
|
|
3060
|
+
selectionMode: "single",
|
|
3061
|
+
isClearable: false,
|
|
3062
|
+
renderStaticInput: false,
|
|
3063
|
+
leadingContent: /* @__PURE__ */ jsx(Monitor, { size: 15 }),
|
|
2002
3064
|
value: bp.id,
|
|
2003
|
-
|
|
2004
|
-
|
|
3065
|
+
items: breakpoints.map((item_4) => ({
|
|
3066
|
+
id: item_4.id,
|
|
3067
|
+
label: `${item_4.label} · ${item_4.width}px`
|
|
3068
|
+
})),
|
|
3069
|
+
onChange: (id_5) => {
|
|
3070
|
+
if (id_5 === null || id_5 === bp.id) return;
|
|
2005
3071
|
setRuntime({});
|
|
2006
3072
|
setManifest((m_2) => ({
|
|
2007
3073
|
...m_2,
|
|
2008
|
-
breakpoint:
|
|
3074
|
+
breakpoint: String(id_5)
|
|
2009
3075
|
}));
|
|
2010
|
-
}
|
|
2011
|
-
|
|
2012
|
-
value: item_1.id,
|
|
2013
|
-
children: [
|
|
2014
|
-
item_1.label,
|
|
2015
|
-
" · ",
|
|
2016
|
-
item_1.width,
|
|
2017
|
-
"px"
|
|
2018
|
-
]
|
|
2019
|
-
}, item_1.id))
|
|
2020
|
-
})]
|
|
3076
|
+
}
|
|
3077
|
+
})
|
|
2021
3078
|
}),
|
|
2022
3079
|
/* @__PURE__ */ jsx("span", { className: "povio-canvas-dock-divider" }),
|
|
2023
3080
|
/* @__PURE__ */ jsx("button", {
|
|
@@ -2050,7 +3107,8 @@ function AppCanvas({ router, examples = emptyExamples, exclude = emptyExclude, e
|
|
|
2050
3107
|
}),
|
|
2051
3108
|
inspectMode && /* @__PURE__ */ jsx(CanvasInspectorPanel, {
|
|
2052
3109
|
inspector,
|
|
2053
|
-
onClose: () => setInspectMode(false)
|
|
3110
|
+
onClose: () => setInspectMode(false),
|
|
3111
|
+
onSelectToken: configuration.revealToken
|
|
2054
3112
|
})
|
|
2055
3113
|
]
|
|
2056
3114
|
}),
|
|
@@ -2351,9 +3409,12 @@ function AppCanvasFrameBridge({ href }) {
|
|
|
2351
3409
|
//#endregion
|
|
2352
3410
|
//#region src/app-canvas/AppCanvasPage.tsx
|
|
2353
3411
|
const APP_CANVAS_PATH = "/_canvas";
|
|
3412
|
+
/** Must match `componentsFrameParam`; kept inline so the canvas page does not load the gallery eagerly. */
|
|
3413
|
+
const componentsParam = "povio-components";
|
|
3414
|
+
const CanvasComponentsFrame = lazy(() => import("./CanvasComponentsFrame-CZXY0Dxi.js"));
|
|
2354
3415
|
/** Ready-made route page. Mount beneath the app's UIConfigurationProvider. */
|
|
2355
3416
|
function AppCanvasPage(t0) {
|
|
2356
|
-
const $ = c(
|
|
3417
|
+
const $ = c(24);
|
|
2357
3418
|
let excludePaths;
|
|
2358
3419
|
let props;
|
|
2359
3420
|
let t1;
|
|
@@ -2369,53 +3430,88 @@ function AppCanvasPage(t0) {
|
|
|
2369
3430
|
t1 = $[3];
|
|
2370
3431
|
}
|
|
2371
3432
|
const canvasPath = t1 === void 0 ? APP_CANVAS_PATH : t1;
|
|
3433
|
+
const updateTheme = ThemeContext.useTheme()?.updateTheme;
|
|
2372
3434
|
let t2;
|
|
2373
|
-
if ($[4] !== excludePaths) {
|
|
2374
|
-
t2 = excludePaths ?? [];
|
|
2375
|
-
$[4] = excludePaths;
|
|
2376
|
-
$[5] = t2;
|
|
2377
|
-
} else t2 = $[5];
|
|
2378
3435
|
let t3;
|
|
2379
|
-
if ($[
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
3436
|
+
if ($[4] !== updateTheme) {
|
|
3437
|
+
t2 = () => {
|
|
3438
|
+
if (!isAppCanvasFrame()) updateTheme?.("light");
|
|
3439
|
+
};
|
|
3440
|
+
t3 = [updateTheme];
|
|
3441
|
+
$[4] = updateTheme;
|
|
3442
|
+
$[5] = t2;
|
|
3443
|
+
$[6] = t3;
|
|
3444
|
+
} else {
|
|
3445
|
+
t2 = $[5];
|
|
3446
|
+
t3 = $[6];
|
|
3447
|
+
}
|
|
3448
|
+
useEffect(t2, t3);
|
|
2385
3449
|
let t4;
|
|
2386
|
-
if ($[
|
|
2387
|
-
t4 = [
|
|
2388
|
-
$[
|
|
2389
|
-
$[
|
|
2390
|
-
} else t4 = $[
|
|
2391
|
-
const exclusions = t4;
|
|
2392
|
-
if (isAppCanvasFrame()) return null;
|
|
3450
|
+
if ($[7] !== excludePaths) {
|
|
3451
|
+
t4 = excludePaths ?? [];
|
|
3452
|
+
$[7] = excludePaths;
|
|
3453
|
+
$[8] = t4;
|
|
3454
|
+
} else t4 = $[8];
|
|
2393
3455
|
let t5;
|
|
2394
|
-
if ($[
|
|
2395
|
-
t5 = /* @__PURE__ */
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
$[12] = props;
|
|
2401
|
-
$[13] = t5;
|
|
2402
|
-
} else t5 = $[13];
|
|
3456
|
+
if ($[9] !== canvasPath || $[10] !== t4) {
|
|
3457
|
+
t5 = /* @__PURE__ */ new Set([...t4, canvasPath]);
|
|
3458
|
+
$[9] = canvasPath;
|
|
3459
|
+
$[10] = t4;
|
|
3460
|
+
$[11] = t5;
|
|
3461
|
+
} else t5 = $[11];
|
|
2403
3462
|
let t6;
|
|
2404
|
-
if ($[
|
|
2405
|
-
t6 =
|
|
2406
|
-
$[
|
|
2407
|
-
|
|
3463
|
+
if ($[12] !== t5) {
|
|
3464
|
+
t6 = [...t5];
|
|
3465
|
+
$[12] = t5;
|
|
3466
|
+
$[13] = t6;
|
|
3467
|
+
} else t6 = $[13];
|
|
3468
|
+
const exclusions = t6;
|
|
3469
|
+
if (isAppCanvasFrame()) {
|
|
3470
|
+
let t7;
|
|
3471
|
+
if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
|
|
3472
|
+
const group = new URLSearchParams(window.location.search).get(componentsParam);
|
|
3473
|
+
t7 = group ? /* @__PURE__ */ jsx(Suspense, {
|
|
3474
|
+
fallback: null,
|
|
3475
|
+
children: /* @__PURE__ */ jsx(CanvasComponentsFrame, { group })
|
|
3476
|
+
}) : null;
|
|
3477
|
+
$[14] = t7;
|
|
3478
|
+
} else t7 = $[14];
|
|
3479
|
+
return t7;
|
|
3480
|
+
}
|
|
2408
3481
|
let t7;
|
|
2409
|
-
if ($[15] !==
|
|
2410
|
-
t7 =
|
|
3482
|
+
if ($[15] !== canvasPath) {
|
|
3483
|
+
t7 = (group_0) => `${canvasPath}?${componentsParam}=${encodeURIComponent(group_0)}`;
|
|
3484
|
+
$[15] = canvasPath;
|
|
3485
|
+
$[16] = t7;
|
|
3486
|
+
} else t7 = $[16];
|
|
3487
|
+
let t8;
|
|
3488
|
+
if ($[17] !== exclusions || $[18] !== props || $[19] !== t7) {
|
|
3489
|
+
t8 = /* @__PURE__ */ jsx(AppCanvas, {
|
|
3490
|
+
...props,
|
|
3491
|
+
excludePaths: exclusions,
|
|
3492
|
+
componentsHref: t7
|
|
3493
|
+
});
|
|
3494
|
+
$[17] = exclusions;
|
|
3495
|
+
$[18] = props;
|
|
3496
|
+
$[19] = t7;
|
|
3497
|
+
$[20] = t8;
|
|
3498
|
+
} else t8 = $[20];
|
|
3499
|
+
let t9;
|
|
3500
|
+
if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
|
|
3501
|
+
t9 = /* @__PURE__ */ jsx(UIConfigurationModal, {});
|
|
3502
|
+
$[21] = t9;
|
|
3503
|
+
} else t9 = $[21];
|
|
3504
|
+
let t10;
|
|
3505
|
+
if ($[22] !== t8) {
|
|
3506
|
+
t10 = /* @__PURE__ */ jsxs("div", {
|
|
2411
3507
|
className: "povio-app-canvas-page",
|
|
2412
3508
|
"aria-label": "App canvas page",
|
|
2413
|
-
children: [
|
|
3509
|
+
children: [t8, t9]
|
|
2414
3510
|
});
|
|
2415
|
-
$[
|
|
2416
|
-
$[
|
|
2417
|
-
} else
|
|
2418
|
-
return
|
|
3511
|
+
$[22] = t8;
|
|
3512
|
+
$[23] = t10;
|
|
3513
|
+
} else t10 = $[23];
|
|
3514
|
+
return t10;
|
|
2419
3515
|
}
|
|
2420
3516
|
//#endregion
|
|
2421
3517
|
export { defaultCanvasBreakpoints as a, layoutCanvasPages as c, AppCanvas as i, AppCanvasPage as n, isAppCanvasFrame as o, AppCanvasFrameBridge as r, discoverCanvasPages as s, APP_CANVAS_PATH as t };
|