@hankchen/canvas-editor-vue 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -2
  3. package/dist/canvas/AlignFloatBar.d.ts +6 -0
  4. package/dist/canvas/CanvasSurface.d.ts +131 -0
  5. package/dist/canvas/ContentTypePill.d.ts +14 -0
  6. package/dist/canvas/ContextMenu.d.ts +14 -0
  7. package/dist/canvas/FindBar.d.ts +13 -0
  8. package/dist/canvas/GuidesOverlay.d.ts +18 -0
  9. package/dist/canvas/Ruler.d.ts +24 -0
  10. package/dist/canvas/TextEditingOverlay.d.ts +70 -0
  11. package/dist/canvas/createBand.d.ts +6 -0
  12. package/dist/canvas/findHighlight.d.ts +12 -0
  13. package/dist/canvas/gizmo.d.ts +24 -0
  14. package/dist/canvas/guideSnap.d.ts +3 -0
  15. package/dist/canvas/index.d.ts +20 -0
  16. package/dist/canvas/resizeHandles.d.ts +3 -0
  17. package/dist/canvas/scheduler.d.ts +2 -0
  18. package/dist/canvas/useDpr.d.ts +10 -0
  19. package/dist/canvas/useFindSession.d.ts +13 -0
  20. package/dist/canvas/useTextEditing.d.ts +53 -0
  21. package/dist/canvas-CS4SmrIO.js +1649 -0
  22. package/dist/canvas.js +2 -0
  23. package/dist/completionAnchor-4lhR2kJz.js +273 -0
  24. package/dist/createLucideIcon-CMq8ZKo2.js +96 -0
  25. package/dist/dist-DuXLYZZ9.js +341 -0
  26. package/dist/index.d.ts +19 -0
  27. package/dist/index.js +16 -0
  28. package/dist/layer-panel/LayerPanel.d.ts +32 -0
  29. package/dist/layer-panel/addMenu.d.ts +18 -0
  30. package/dist/layer-panel/index.d.ts +7 -0
  31. package/dist/layer-panel/useLayerPanel.d.ts +12 -0
  32. package/dist/layer-panel-ArP66_vZ.js +652 -0
  33. package/dist/layer-panel.js +2 -0
  34. package/dist/layerPath-BRZK9ka1.js +2160 -0
  35. package/dist/panel-theme.css +254 -0
  36. package/dist/property-panel/PropertyField.d.ts +65 -0
  37. package/dist/property-panel/PropertyPanel.d.ts +6 -0
  38. package/dist/property-panel/controlStyles.d.ts +17 -0
  39. package/dist/property-panel/controls.d.ts +3 -0
  40. package/dist/property-panel/fieldSchema.d.ts +116 -0
  41. package/dist/property-panel/fields/AlignField.d.ts +11 -0
  42. package/dist/property-panel/fields/AnchorDisclosureField.d.ts +16 -0
  43. package/dist/property-panel/fields/BooleanField.d.ts +13 -0
  44. package/dist/property-panel/fields/BorderField.d.ts +14 -0
  45. package/dist/property-panel/fields/BorderWidthInput.d.ts +14 -0
  46. package/dist/property-panel/fields/ColorField.d.ts +13 -0
  47. package/dist/property-panel/fields/FontField.d.ts +15 -0
  48. package/dist/property-panel/fields/ImageSrcField.d.ts +20 -0
  49. package/dist/property-panel/fields/NumberField.d.ts +13 -0
  50. package/dist/property-panel/fields/PaddingField.d.ts +14 -0
  51. package/dist/property-panel/fields/PairField.d.ts +19 -0
  52. package/dist/property-panel/fields/SelectField.d.ts +11 -0
  53. package/dist/property-panel/fields/ShorthandModeButton.d.ts +13 -0
  54. package/dist/property-panel/fields/TextField.d.ts +13 -0
  55. package/dist/property-panel/fields/TextareaField.d.ts +13 -0
  56. package/dist/property-panel/fields/ValueTypeSegmented.d.ts +10 -0
  57. package/dist/property-panel/fields/index.d.ts +16 -0
  58. package/dist/property-panel/fontPicker.d.ts +13 -0
  59. package/dist/property-panel/imageUpload.d.ts +11 -0
  60. package/dist/property-panel/index.d.ts +13 -0
  61. package/dist/property-panel/shorthand.d.ts +28 -0
  62. package/dist/property-panel/usePropertyPanel.d.ts +51 -0
  63. package/dist/property-panel/useShorthandMode.d.ts +18 -0
  64. package/dist/property-panel-jt_rsTVW.js +1719 -0
  65. package/dist/property-panel.js +2 -0
  66. package/dist/shared/DropdownMenu.d.ts +47 -0
  67. package/dist/shared/ExpressionCompletionPopup.d.ts +14 -0
  68. package/dist/shared/HelpDialog.d.ts +12 -0
  69. package/dist/shared/PanelIcon.d.ts +14 -0
  70. package/dist/shared/completion.d.ts +49 -0
  71. package/dist/shared/completionAnchor.d.ts +28 -0
  72. package/dist/shared/editableTarget.d.ts +5 -0
  73. package/dist/shared/expressionContext.d.ts +22 -0
  74. package/dist/shared/index.d.ts +37 -0
  75. package/dist/shared/rowsPathCompletionSource.d.ts +3 -0
  76. package/dist/shared/shortcutsHelp.d.ts +30 -0
  77. package/dist/shared/uploadFile.d.ts +2 -0
  78. package/dist/shared/useDataSourceSchema.d.ts +3 -0
  79. package/dist/shared/useDropdownMenu.d.ts +51 -0
  80. package/dist/shared/useExpressionCompletion.d.ts +45 -0
  81. package/dist/shared/useHistory.d.ts +7 -0
  82. package/dist/shared/usePathCompletion.d.ts +18 -0
  83. package/dist/shared/useSelection.d.ts +3 -0
  84. package/dist/shared/useShortcuts.d.ts +2 -0
  85. package/dist/shared/useShortcutsHelp.d.ts +9 -0
  86. package/dist/shared/useTransientFeedback.d.ts +10 -0
  87. package/dist/shared/useViewport.d.ts +3 -0
  88. package/dist/shared-D9zYUQaw.js +123 -0
  89. package/dist/shared.js +9 -0
  90. package/dist/status-bar/StatusBar.d.ts +17 -0
  91. package/dist/status-bar/index.d.ts +9 -0
  92. package/dist/status-bar/layerGeometryLabel.d.ts +13 -0
  93. package/dist/status-bar/layerPathLabel.d.ts +2 -0
  94. package/dist/status-bar/useDoc.d.ts +3 -0
  95. package/dist/status-bar-BhhrVoBZ.js +194 -0
  96. package/dist/status-bar.js +2 -0
  97. package/dist/style.css +2 -0
  98. package/dist/uploadFile-CutE_xI-.js +330 -0
  99. package/dist/useDataSourceSchema-C924m8fc.js +237 -0
  100. package/dist/usePathCompletion-DkHoGla4.js +228 -0
  101. package/dist/useShortcutsHelp-DTC3yRil.js +19 -0
  102. package/dist/useTransientFeedback-gS9Xa9GY.js +477 -0
  103. package/dist/useViewport-BLe2ise1.js +18 -0
  104. package/package.json +76 -3
@@ -0,0 +1,1719 @@
1
+ import { B as e, D as t, F as n, G as r, H as i, I as a, L as o, M as s, N as c, O as l, P as u, S as d, U as f, _ as p, a as m, b as h, d as g, g as _, h as v, j as y, k as b, m as x, p as S, r as C, s as w, u as T, v as E, w as D, y as O, z as k } from "./layerPath-BRZK9ka1.js";
2
+ import { t as A } from "./createLucideIcon-CMq8ZKo2.js";
3
+ import { a as j, c as ee, d as te, f as ne, i as re, l as ie, n as M, p as ae, r as N, s as oe, t as se, u as ce } from "./dist-DuXLYZZ9.js";
4
+ import { i as P, r as le } from "./completionAnchor-4lhR2kJz.js";
5
+ import { i as ue, n as de, r as fe, t as F } from "./uploadFile-CutE_xI-.js";
6
+ import { n as pe, r as me, t as he } from "./usePathCompletion-DkHoGla4.js";
7
+ var ge = A({
8
+ name: "grid-2x2",
9
+ size: 24,
10
+ node: [
11
+ ["path", {
12
+ d: "M12 3v18",
13
+ key: "108xh3"
14
+ }],
15
+ ["path", {
16
+ d: "M3 12h18",
17
+ key: "1i2n21"
18
+ }],
19
+ ["rect", {
20
+ x: "3",
21
+ y: "3",
22
+ width: "18",
23
+ height: "18",
24
+ rx: "2",
25
+ key: "h1oib"
26
+ }]
27
+ ],
28
+ aliases: ["grid-2-x-2"]
29
+ }), _e = A({
30
+ name: "square-split-vertical",
31
+ size: 24,
32
+ node: [
33
+ ["path", {
34
+ d: "M2 12h20",
35
+ key: "9i4pu4"
36
+ }],
37
+ ["path", {
38
+ d: "M21 16v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3",
39
+ key: "14rx03"
40
+ }],
41
+ ["path", {
42
+ d: "M3 8V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v3",
43
+ key: "1haecz"
44
+ }]
45
+ ],
46
+ aliases: ["split-square-vertical"]
47
+ }), ve = A({
48
+ name: "square",
49
+ size: 24,
50
+ node: [["rect", {
51
+ width: "18",
52
+ height: "18",
53
+ x: "3",
54
+ y: "3",
55
+ rx: "2",
56
+ key: "afitv7"
57
+ }]]
58
+ });
59
+ //#endregion
60
+ //#region ../canvas-editor/src/shared/resourceStatus.ts
61
+ function ye(e, t) {
62
+ if (e.type !== "ImageLayer") return !1;
63
+ if (e.expression !== null || e.src === null || j(e) <= 0 || re(e) <= 0) return !0;
64
+ if (t !== void 0) {
65
+ let n = t[e.src];
66
+ if (n !== void 0 && n !== "done") return !0;
67
+ }
68
+ return !1;
69
+ }
70
+ //#endregion
71
+ //#region src/property-panel/fieldSchema.ts
72
+ var be = "当前层内容未绘制,padding 不影响预览", I = {
73
+ title: "位置与尺寸",
74
+ fields: [
75
+ {
76
+ key: ["position"],
77
+ label: "位置",
78
+ control: "pair",
79
+ items: [{
80
+ key: ["x"],
81
+ label: "X",
82
+ control: "number",
83
+ integer: !0
84
+ }, {
85
+ key: ["y"],
86
+ label: "Y",
87
+ control: "number",
88
+ integer: !0
89
+ }]
90
+ },
91
+ {
92
+ key: ["shape"],
93
+ label: "尺寸",
94
+ control: "pair",
95
+ items: [{
96
+ key: ["width"],
97
+ label: "宽",
98
+ control: "number",
99
+ integer: !0,
100
+ min: 0,
101
+ auto: {
102
+ key: ["autoWidth"],
103
+ placeholder: "自动"
104
+ }
105
+ }, {
106
+ key: ["height"],
107
+ label: "高",
108
+ control: "number",
109
+ integer: !0,
110
+ min: 0,
111
+ auto: { key: ["autoHeight"] }
112
+ }]
113
+ },
114
+ {
115
+ key: ["angle"],
116
+ label: "旋转角",
117
+ control: "number",
118
+ integer: !0,
119
+ visibleWhen: (e) => e.type === "TextLayer"
120
+ },
121
+ {
122
+ key: ["position", "anchor"],
123
+ label: "锚点",
124
+ control: "anchor"
125
+ }
126
+ ]
127
+ }, L = {
128
+ title: "对齐",
129
+ fields: [{
130
+ key: ["align", "horizontal"],
131
+ label: "水平",
132
+ control: "align",
133
+ domain: M
134
+ }, {
135
+ key: ["align", "vertical"],
136
+ label: "垂直",
137
+ control: "align",
138
+ domain: N
139
+ }]
140
+ }, R = {
141
+ title: "形状",
142
+ fields: [
143
+ {
144
+ key: ["shape", "backgroundColor"],
145
+ label: "背景色",
146
+ control: "color",
147
+ nullable: !0
148
+ },
149
+ {
150
+ key: ["shape", "lineHeight"],
151
+ label: "行高倍数",
152
+ control: "number",
153
+ step: .1,
154
+ min: 0,
155
+ visibleWhen: (e) => e.type === "TextLayer"
156
+ },
157
+ {
158
+ key: ["shape", "padding"],
159
+ label: "内边距",
160
+ control: "padding",
161
+ title: "内边距作用于内容盒,不改变图层尺寸",
162
+ hint: (e, t) => ye(e, t) ? be : null
163
+ },
164
+ {
165
+ key: ["shape", "border"],
166
+ label: "边框",
167
+ control: "border"
168
+ }
169
+ ]
170
+ }, xe = {
171
+ ImageLayer: [
172
+ I,
173
+ L,
174
+ R,
175
+ {
176
+ title: "图片",
177
+ fields: [{
178
+ key: ["src"],
179
+ label: "资源地址",
180
+ control: "imageSrc",
181
+ data: !0
182
+ }]
183
+ }
184
+ ],
185
+ TextLayer: [
186
+ I,
187
+ L,
188
+ R,
189
+ {
190
+ title: "文本",
191
+ fields: [
192
+ {
193
+ key: ["text"],
194
+ label: "内容",
195
+ control: "textarea",
196
+ data: !0
197
+ },
198
+ {
199
+ key: ["font"],
200
+ label: "字体",
201
+ control: "font"
202
+ },
203
+ {
204
+ key: ["fontSize"],
205
+ label: "字号",
206
+ control: "number",
207
+ integer: !0,
208
+ min: 1
209
+ },
210
+ {
211
+ key: ["fontColor"],
212
+ label: "字色",
213
+ control: "color"
214
+ },
215
+ {
216
+ key: ["autowrap"],
217
+ label: "自动换行",
218
+ control: "boolean"
219
+ }
220
+ ]
221
+ }
222
+ ],
223
+ QrCodeLayer: [
224
+ I,
225
+ L,
226
+ R,
227
+ {
228
+ title: "二维码",
229
+ fields: [{
230
+ key: ["value"],
231
+ label: "内容",
232
+ control: "text",
233
+ data: !0
234
+ }]
235
+ }
236
+ ],
237
+ TableLayer: [
238
+ I,
239
+ L,
240
+ R,
241
+ {
242
+ title: "数据",
243
+ fields: [{
244
+ key: ["rowsPath"],
245
+ label: "数据行路径",
246
+ control: "text",
247
+ placeholder: "如 order.items",
248
+ nonEmpty: !0,
249
+ completion: "rowsPath",
250
+ visibleWhen: (e) => e.type === "TableLayer" && e.template !== null
251
+ }]
252
+ }
253
+ ],
254
+ TableRowLayer: [
255
+ I,
256
+ L,
257
+ R
258
+ ],
259
+ TableCellLayer: [
260
+ I,
261
+ L,
262
+ R
263
+ ],
264
+ TableRowTemplate: [{
265
+ title: "行模板(行宽由表宽同步)",
266
+ fields: [{
267
+ key: ["shape", "height"],
268
+ label: "高",
269
+ control: "number",
270
+ integer: !0,
271
+ min: 0
272
+ }, {
273
+ key: ["shape", "autoHeight"],
274
+ label: "高自适应",
275
+ control: "boolean"
276
+ }]
277
+ }]
278
+ };
279
+ function Se(e) {
280
+ return xe[e] ?? [];
281
+ }
282
+ function Ce(e) {
283
+ if (e[e.length - 1] === "content") return C(e) ? "templateContent" : "content";
284
+ let t = e[e.length - 2];
285
+ return t === "rows" ? "row" : t === "cells" ? "cell" : "root";
286
+ }
287
+ var we = {
288
+ root: [],
289
+ cell: [],
290
+ row: ["shape.width", "shape.autoWidth"],
291
+ content: [
292
+ "shape.width",
293
+ "shape.autoWidth",
294
+ "shape.height",
295
+ "shape.autoHeight"
296
+ ],
297
+ templateContent: ["shape.width", "shape.autoWidth"]
298
+ };
299
+ function z(e, t) {
300
+ return [...e.key, ...t.key];
301
+ }
302
+ function Te(e, t) {
303
+ let n = new Set(we[Ce(e)]), r = [];
304
+ for (let e of Se(t.type)) {
305
+ let i = [];
306
+ for (let r of e.fields) {
307
+ if (r.items) {
308
+ let e = r.items.filter((e) => !n.has(z(r, e).join(".")) && (!e.visibleWhen || e.visibleWhen(t)));
309
+ e.length > 0 && i.push({
310
+ ...r,
311
+ items: e
312
+ });
313
+ continue;
314
+ }
315
+ n.has(r.key.join(".")) || (!r.visibleWhen || r.visibleWhen(t)) && i.push(r);
316
+ }
317
+ i.length > 0 && r.push({
318
+ title: e.title,
319
+ fields: i
320
+ });
321
+ }
322
+ return r;
323
+ }
324
+ var B = [{
325
+ title: "画布",
326
+ fields: [{
327
+ key: ["width"],
328
+ label: "宽",
329
+ control: "number",
330
+ integer: !0,
331
+ min: 1
332
+ }, {
333
+ key: ["height"],
334
+ label: "高",
335
+ control: "number",
336
+ integer: !0,
337
+ min: 1
338
+ }]
339
+ }];
340
+ function V(e, t) {
341
+ let n = e;
342
+ for (let e = 0; e < t.length; e += 1) {
343
+ if (typeof n != "object" || !n) return { ok: !1 };
344
+ n = n[t[e]];
345
+ }
346
+ return n === void 0 ? { ok: !1 } : {
347
+ ok: !0,
348
+ value: n
349
+ };
350
+ }
351
+ //#endregion
352
+ //#region src/property-panel/fields/AlignField.vue?vue&type=script&setup=true&lang.ts
353
+ var Ee = ["aria-label"], De = [
354
+ "aria-pressed",
355
+ "title",
356
+ "onClick"
357
+ ], Oe = {
358
+ key: 1,
359
+ class: "truncate px-1 text-[10px] leading-none"
360
+ }, ke = /* @__PURE__ */ h({
361
+ __name: "AlignField",
362
+ props: {
363
+ field: {},
364
+ modelValue: {}
365
+ },
366
+ emits: ["change"],
367
+ setup(e, { emit: n }) {
368
+ let i = e, a = n, o = {
369
+ [M.join(".")]: {
370
+ left: {
371
+ icon: ee,
372
+ title: "左对齐"
373
+ },
374
+ center: {
375
+ icon: ne,
376
+ title: "居中对齐"
377
+ },
378
+ right: {
379
+ icon: ce,
380
+ title: "右对齐"
381
+ }
382
+ },
383
+ [N.join(".")]: {
384
+ top: {
385
+ icon: ie,
386
+ title: "顶对齐"
387
+ },
388
+ center: {
389
+ icon: ae,
390
+ title: "居中对齐"
391
+ },
392
+ bottom: {
393
+ icon: te,
394
+ title: "底对齐"
395
+ }
396
+ }
397
+ }, s = S(() => {
398
+ let e = i.field.domain ?? [], t = o[e.join(".")];
399
+ return e.map((e) => ({
400
+ value: e,
401
+ icon: t?.[e]?.icon,
402
+ title: t?.[e] ? `${i.field.label}:${t[e].title}` : `${i.field.label}:${e}`
403
+ }));
404
+ });
405
+ function c(e) {
406
+ e !== i.modelValue && a("change", e);
407
+ }
408
+ return (n, i) => (t(), p("span", {
409
+ class: "cn-align flex h-7 min-w-0 flex-1 overflow-hidden rounded-md border border-cn-field-line bg-cn-field",
410
+ role: "group",
411
+ "aria-label": e.field.label
412
+ }, [(t(!0), p(g, null, b(s.value, (n, i) => (t(), p("button", {
413
+ key: n.value,
414
+ type: "button",
415
+ class: f(["cn-align__option flex min-w-0 flex-1 items-center justify-center p-0 transition-colors duration-100 focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cn-accent/40", [i > 0 ? "border-l border-cn-field-line" : "", n.value === e.modelValue ? "cn-align__option--active bg-cn-accent-soft text-cn-accent" : "text-cn-muted hover:text-cn-fg"]]),
416
+ "aria-pressed": n.value === e.modelValue,
417
+ title: n.title,
418
+ onClick: T((e) => c(n.value), ["prevent"])
419
+ }, [n.icon ? (t(), v(P, {
420
+ key: 0,
421
+ icon: n.icon
422
+ }, null, 8, ["icon"])) : (t(), p("span", Oe, r(n.value), 1))], 10, De))), 128))], 8, Ee));
423
+ }
424
+ }), Ae = { class: "block" }, je = ["aria-expanded", "title"], Me = { class: "cn-prop-field__label shrink-0 select-none truncate text-[11px] leading-none text-cn-muted" }, Ne = { class: "flex shrink-0 items-center gap-1.5" }, Pe = {
425
+ viewBox: "0 0 24 24",
426
+ class: "size-3.5",
427
+ "aria-hidden": "true"
428
+ }, Fe = [
429
+ "cx",
430
+ "cy",
431
+ "r"
432
+ ], Ie = {
433
+ key: 0,
434
+ class: "mt-2 flex justify-end"
435
+ }, Le = {
436
+ class: "cn-anchor grid w-[66px] shrink-0 grid-cols-3 gap-[3px]",
437
+ role: "group",
438
+ "aria-label": "九宫锚点"
439
+ }, Re = [
440
+ "aria-pressed",
441
+ "title",
442
+ "onClick"
443
+ ], H = /* @__PURE__ */ h({
444
+ __name: "AnchorDisclosureField",
445
+ props: {
446
+ field: {},
447
+ modelValue: {},
448
+ expanded: { type: Boolean }
449
+ },
450
+ emits: ["change", "toggle"],
451
+ setup(e, { emit: n }) {
452
+ let o = e, s = n, c = a(se), l = Array.from({ length: 9 }, (e, t) => ({
453
+ index: t,
454
+ cx: 4 + t % 3 * 8,
455
+ cy: 4 + Math.floor(t / 3) * 8
456
+ })), u = S(() => {
457
+ let e = o.modelValue.includes("top") ? 0 : o.modelValue.includes("bottom") ? 2 : 1, t = o.modelValue.includes("left") ? 0 : o.modelValue.includes("right") ? 2 : 1;
458
+ return e * 3 + t;
459
+ });
460
+ function d(e) {
461
+ s("change", e);
462
+ }
463
+ return (n, a) => (t(), p("span", Ae, [x("button", {
464
+ type: "button",
465
+ class: "cn-anchor-disclosure__header flex w-full items-center justify-between gap-2",
466
+ "aria-expanded": e.expanded,
467
+ title: e.expanded ? "收起锚点" : `锚点:${e.modelValue}(点击展开调整)`,
468
+ onClick: a[0] ||= (e) => s("toggle")
469
+ }, [x("span", Me, r(e.field.label), 1), x("span", Ne, [(t(), p("svg", Pe, [(t(!0), p(g, null, b(i(l), (e) => (t(), p("circle", {
470
+ key: e.index,
471
+ cx: e.cx,
472
+ cy: e.cy,
473
+ r: e.index === u.value ? 3.2 : 2.2,
474
+ class: f(e.index === u.value ? "fill-cn-accent" : "fill-cn-muted/35")
475
+ }, null, 10, Fe))), 128))])), O(P, {
476
+ icon: i(oe),
477
+ class: f(["text-cn-muted transition-transform duration-150", { "rotate-180": e.expanded }])
478
+ }, null, 8, ["icon", "class"])])], 8, je), e.expanded ? (t(), p("span", Ie, [x("span", Le, [(t(!0), p(g, null, b(i(c), (n) => (t(), p("button", {
479
+ key: n,
480
+ type: "button",
481
+ class: f(["cn-anchor__cell relative aspect-square min-w-0 rounded-[4px] border p-0 transition-colors duration-100", n === e.modelValue ? "cn-anchor__cell--active border-cn-accent bg-cn-accent shadow-[0_0_8px_rgba(56,189,248,0.35)]" : "border-cn-field-line bg-cn-field hover:border-cn-muted/50"]),
482
+ "aria-pressed": n === e.modelValue,
483
+ title: n,
484
+ onClick: (e) => d(n)
485
+ }, null, 10, Re))), 128))])])) : _("", !0)]));
486
+ }
487
+ }), ze = { class: "cn-bool relative inline-flex h-4 w-7 shrink-0 cursor-pointer items-center" }, Be = ["checked"], Ve = /* @__PURE__ */ h({
488
+ __name: "BooleanField",
489
+ props: {
490
+ field: {},
491
+ modelValue: { type: Boolean }
492
+ },
493
+ emits: ["change"],
494
+ setup(e, { emit: n }) {
495
+ let r = e, i = n, a = k(null);
496
+ async function o(e) {
497
+ i("change", e.target.checked), await D(), a.value && (a.value.checked = r.modelValue);
498
+ }
499
+ return c(() => {
500
+ a.value && (a.value.checked = r.modelValue);
501
+ }), (n, r) => (t(), p("label", ze, [
502
+ x("input", {
503
+ ref_key: "inputRef",
504
+ ref: a,
505
+ class: "cn-bool__input peer sr-only",
506
+ type: "checkbox",
507
+ checked: e.modelValue,
508
+ onChange: o
509
+ }, null, 40, Be),
510
+ r[0] ||= x("span", { class: "absolute inset-0 rounded-full border border-cn-field-line bg-cn-field transition-colors duration-150 peer-checked:border-cn-accent/60 peer-checked:bg-cn-accent/30 peer-focus-visible:ring-[3px] peer-focus-visible:ring-cn-accent/20" }, null, -1),
511
+ r[1] ||= x("span", { class: "relative mx-0.5 size-3 rounded-full bg-cn-muted shadow-sm transition-transform duration-150 peer-checked:translate-x-3 peer-checked:bg-cn-accent" }, null, -1)
512
+ ]));
513
+ }
514
+ }), U = {
515
+ 1: [{
516
+ label: "四边",
517
+ rep: "top",
518
+ sides: [
519
+ "top",
520
+ "bottom",
521
+ "left",
522
+ "right"
523
+ ]
524
+ }],
525
+ 2: [{
526
+ label: "上下",
527
+ rep: "top",
528
+ sides: ["top", "bottom"]
529
+ }, {
530
+ label: "左右",
531
+ rep: "left",
532
+ sides: ["left", "right"]
533
+ }],
534
+ 4: [
535
+ {
536
+ label: "上",
537
+ rep: "top",
538
+ sides: ["top"]
539
+ },
540
+ {
541
+ label: "下",
542
+ rep: "bottom",
543
+ sides: ["bottom"]
544
+ },
545
+ {
546
+ label: "左",
547
+ rep: "left",
548
+ sides: ["left"]
549
+ },
550
+ {
551
+ label: "右",
552
+ rep: "right",
553
+ sides: ["right"]
554
+ }
555
+ ]
556
+ };
557
+ function He(e) {
558
+ return e === 1 ? 2 : e === 2 ? 4 : 1;
559
+ }
560
+ function Ue(e) {
561
+ return e.top === e.bottom && e.bottom === e.left && e.left === e.right ? 1 : e.top === e.bottom && e.left === e.right ? 2 : 4;
562
+ }
563
+ function We(e, t) {
564
+ if (t === 1) {
565
+ let { top: t } = e;
566
+ return {
567
+ top: t,
568
+ bottom: t,
569
+ left: t,
570
+ right: t
571
+ };
572
+ }
573
+ if (t === 2) {
574
+ let { top: t, left: n } = e;
575
+ return {
576
+ top: t,
577
+ bottom: t,
578
+ left: n,
579
+ right: n
580
+ };
581
+ }
582
+ return e;
583
+ }
584
+ function Ge(e, t) {
585
+ return e.top === t.top && e.bottom === t.bottom && e.left === t.left && e.right === t.right;
586
+ }
587
+ function W(e, t) {
588
+ return e === null || t === null ? e === t : e.width === t.width && e.color === t.color;
589
+ }
590
+ function Ke(e) {
591
+ let { top: t, bottom: n, left: r, right: i } = e;
592
+ return t === null && n === null && r === null && i === null || t !== null && W(t, n) && W(t, r) && W(t, i) ? 1 : W(t, n) && W(r, i) ? 2 : 4;
593
+ }
594
+ function qe(e, t) {
595
+ let n = (e) => e === null ? null : { ...e };
596
+ if (t === 1) {
597
+ let t = n(e.top);
598
+ return {
599
+ top: t,
600
+ bottom: n(t),
601
+ left: n(t),
602
+ right: n(t)
603
+ };
604
+ }
605
+ if (t === 2) {
606
+ let t = n(e.top), r = n(e.left);
607
+ return {
608
+ top: t,
609
+ bottom: n(t),
610
+ left: r,
611
+ right: n(r)
612
+ };
613
+ }
614
+ return e;
615
+ }
616
+ function Je(e, t) {
617
+ return W(e.top, t.top) && W(e.bottom, t.bottom) && W(e.left, t.left) && W(e.right, t.right);
618
+ }
619
+ //#endregion
620
+ //#region src/property-panel/useShorthandMode.ts
621
+ function G(e, t) {
622
+ let n = S(() => t(e())), r = k(null), i = S(() => r.value ?? n.value);
623
+ s(e, () => {
624
+ r.value = null;
625
+ });
626
+ function a() {
627
+ let e = i.value, t = He(e);
628
+ return r.value = t, {
629
+ from: e,
630
+ to: t
631
+ };
632
+ }
633
+ return {
634
+ mode: i,
635
+ cycle: a
636
+ };
637
+ }
638
+ //#endregion
639
+ //#region src/property-panel/controlStyles.ts
640
+ var K = "h-7 flex-1 w-full min-w-0 rounded-md border border-cn-field-line bg-cn-field text-[11.5px] leading-none text-cn-fg outline-none transition-[border-color,box-shadow,background-color] duration-100 placeholder:text-cn-muted/60 hover:border-cn-muted/40 focus:border-cn-accent/70 focus:ring-[3px] focus:ring-cn-accent/15 disabled:cursor-not-allowed disabled:opacity-40 disabled:hover:border-cn-field-line", q = `${K} text-right font-mono tabular-nums`, J = K, Ye = "w-full flex-1 min-w-0 resize-y rounded-md border border-cn-field-line bg-cn-field px-2 py-1.5 text-[11.5px] leading-5 text-cn-fg outline-none transition-[border-color,box-shadow] duration-100 placeholder:text-cn-muted/60 hover:border-cn-muted/40 focus:border-cn-accent/70 focus:ring-[3px] focus:ring-cn-accent/15 disabled:cursor-not-allowed disabled:opacity-40", Xe = "size-7 shrink-0 cursor-pointer self-center rounded-md border border-cn-field-line bg-cn-field p-0.5 transition-colors hover:border-cn-muted/40 disabled:cursor-not-allowed disabled:opacity-40", Ze = ["aria-label"], Qe = /* @__PURE__ */ h({
641
+ __name: "BorderWidthInput",
642
+ props: {
643
+ value: {},
644
+ label: {}
645
+ },
646
+ emits: ["input", "change"],
647
+ setup(e, { emit: r }) {
648
+ let a = e, o = r, c = k(a.value === null ? "" : String(a.value)), l = k(!1);
649
+ s(() => a.value, (e) => {
650
+ l.value || (c.value = e === null ? "" : String(e));
651
+ });
652
+ function u(e) {
653
+ return Math.max(0, Math.trunc(e));
654
+ }
655
+ function d(e) {
656
+ if (e.value.trim() === "") return null;
657
+ let t = Number(e.value);
658
+ return Number.isFinite(t) ? t : null;
659
+ }
660
+ function m(e) {
661
+ return e === null ? "" : String(e);
662
+ }
663
+ function h(e) {
664
+ let t = e.target;
665
+ c.value = t.value;
666
+ let n = d(t);
667
+ n !== null && o("input", u(n));
668
+ }
669
+ function g(e) {
670
+ let t = d(e.target);
671
+ if (t === null) {
672
+ c.value = m(a.value);
673
+ return;
674
+ }
675
+ let n = u(t);
676
+ c.value = n === 0 ? "" : String(n), o("change", n);
677
+ }
678
+ return (r, a) => n((t(), p("input", {
679
+ "onUpdate:modelValue": a[0] ||= (e) => c.value = e,
680
+ class: f(["cn-field cn-field--number min-w-0 flex-1", i(q)]),
681
+ type: "number",
682
+ "aria-label": e.label,
683
+ min: 0,
684
+ step: "1",
685
+ placeholder: "无边框",
686
+ title: "宽度归 0 即关闭该边",
687
+ onInput: h,
688
+ onFocus: a[1] ||= (e) => l.value = !0,
689
+ onBlur: g,
690
+ onChange: g
691
+ }, null, 42, Ze)), [[w, c.value]]);
692
+ }
693
+ }), $e = ["aria-label", "title"], Y = /* @__PURE__ */ h({
694
+ __name: "ShorthandModeButton",
695
+ props: {
696
+ mode: {},
697
+ label: {}
698
+ },
699
+ emits: ["cycle"],
700
+ setup(e, { emit: n }) {
701
+ let r = e, i = n, a = {
702
+ 1: {
703
+ icon: ve,
704
+ title: "统一值"
705
+ },
706
+ 2: {
707
+ icon: _e,
708
+ title: "上下/左右"
709
+ },
710
+ 4: {
711
+ icon: ge,
712
+ title: "四边独立"
713
+ }
714
+ }, o = S(() => a[r.mode]), s = S(() => `${r.label}:${o.value.title}(点击切换值模式)`);
715
+ return (e, n) => (t(), p("button", {
716
+ type: "button",
717
+ class: "cn-props__mode-toggle shrink-0",
718
+ "aria-label": s.value,
719
+ title: s.value,
720
+ onClick: n[0] ||= T((e) => i("cycle"), ["prevent"])
721
+ }, [O(P, {
722
+ icon: o.value.icon,
723
+ size: 12
724
+ }, null, 8, ["icon"])], 8, $e));
725
+ }
726
+ }), et = { class: "cn-border flex w-full min-w-0 items-center gap-1" }, tt = { class: "grid min-w-0 flex-1 gap-1 grid-cols-1" }, nt = { class: "w-5 shrink-0 select-none text-[10px] leading-none text-cn-muted" }, rt = [
727
+ "value",
728
+ "disabled",
729
+ "onInput",
730
+ "onChange"
731
+ ], it = "#000000", at = /* @__PURE__ */ h({
732
+ __name: "BorderField",
733
+ props: {
734
+ field: {},
735
+ modelValue: {}
736
+ },
737
+ emits: ["input", "change"],
738
+ setup(e, { emit: n }) {
739
+ let a = e, o = n, { mode: s, cycle: c } = G(() => a.modelValue, Ke), l = S(() => U[s.value]);
740
+ function u(e) {
741
+ return a.modelValue[e.rep]?.width ?? null;
742
+ }
743
+ function d(e) {
744
+ return a.modelValue[e.rep]?.color ?? it;
745
+ }
746
+ function f(e, t, n) {
747
+ let r = { ...a.modelValue };
748
+ for (let n of e.sides) r[n] = t === null ? null : { ...t };
749
+ o(n ? "change" : "input", r);
750
+ }
751
+ function m(e, t, n) {
752
+ let r = a.modelValue[e.rep]?.color ?? it;
753
+ f(e, t <= 0 ? null : {
754
+ width: t,
755
+ color: r
756
+ }, n);
757
+ }
758
+ function h(e, t, n) {
759
+ let r = a.modelValue[e.rep];
760
+ if (!r) return;
761
+ let i = t.target.value.trim();
762
+ i !== "" && f(e, {
763
+ width: r.width,
764
+ color: i
765
+ }, n);
766
+ }
767
+ function _() {
768
+ let { from: e, to: t } = c();
769
+ if (t < e) {
770
+ let e = qe(a.modelValue, t);
771
+ Je(e, a.modelValue) || o("change", e);
772
+ }
773
+ }
774
+ return (n, a) => (t(), p("span", et, [O(Y, {
775
+ mode: i(s),
776
+ label: "边框",
777
+ onCycle: _
778
+ }, null, 8, ["mode"]), x("span", tt, [(t(!0), p(g, null, b(l.value, (n) => (t(), p("label", {
779
+ key: n.rep,
780
+ class: "flex items-center gap-1.5"
781
+ }, [
782
+ x("span", nt, r(n.label), 1),
783
+ O(Qe, {
784
+ class: "cn-border__width",
785
+ value: u(n),
786
+ label: n.label,
787
+ onInput: (e) => m(n, e, !1),
788
+ onChange: (e) => m(n, e, !0)
789
+ }, null, 8, [
790
+ "value",
791
+ "label",
792
+ "onInput",
793
+ "onChange"
794
+ ]),
795
+ x("input", {
796
+ class: "cn-border__color size-6 shrink-0 cursor-pointer self-center rounded-md border border-cn-field-line bg-cn-field p-0.5 transition-colors hover:border-cn-muted/40 disabled:cursor-not-allowed disabled:opacity-40",
797
+ type: "color",
798
+ title: "边框颜色",
799
+ value: d(n),
800
+ disabled: e.modelValue[n.rep] === null,
801
+ onInput: (e) => h(n, e, !1),
802
+ onChange: (e) => h(n, e, !0)
803
+ }, null, 40, rt)
804
+ ]))), 128))])]));
805
+ }
806
+ }), ot = Symbol("canvas-font-picker");
807
+ function st() {
808
+ return d(ot, null);
809
+ }
810
+ //#endregion
811
+ //#region src/property-panel/fields/FontField.vue?vue&type=script&setup=true&lang.ts
812
+ var ct = ["value"], lt = {
813
+ key: 1,
814
+ class: "flex flex-1 items-center gap-1.5"
815
+ }, ut = ["value"], dt = ["value"], ft = [
816
+ "disabled",
817
+ "title",
818
+ "data-upload-error"
819
+ ], pt = /* @__PURE__ */ h({
820
+ __name: "FontField",
821
+ props: {
822
+ field: {},
823
+ modelValue: {}
824
+ },
825
+ emits: ["input", "change"],
826
+ setup(e, { emit: n }) {
827
+ let a = e, o = n, s = st(), c = S(() => {
828
+ if (s === null) return [];
829
+ let e = [{
830
+ label: "内置默认字体",
831
+ value: ""
832
+ }];
833
+ for (let t of s.entries.value) t.ref !== "" && e.push({
834
+ label: t.label,
835
+ value: t.ref
836
+ });
837
+ let t = a.modelValue;
838
+ return t !== "" && !e.some((e) => e.value === t) && e.push({
839
+ label: `${l(t)}(清单外引用)`,
840
+ value: t
841
+ }), e;
842
+ });
843
+ function l(e) {
844
+ return e.startsWith("data:") ? "自定义字体(内联)" : e.split("/").pop() || e;
845
+ }
846
+ function u(e) {
847
+ o("change", e.target.value);
848
+ }
849
+ let d = !1;
850
+ function m(e) {
851
+ d || e.isComposing || o("input", e.target.value);
852
+ }
853
+ function h() {
854
+ d = !0;
855
+ }
856
+ function v(e) {
857
+ d = !1, o("input", e.target.value);
858
+ }
859
+ function y(e) {
860
+ d = !1, o("change", e.target.value);
861
+ }
862
+ let C = k(!1), w = k(null), T = k(null);
863
+ function E() {
864
+ w.value = null, T.value?.click();
865
+ }
866
+ async function D(e) {
867
+ let t = e.target, n = t.files?.[0];
868
+ if (t.value = "", s !== null && n && !C.value) {
869
+ C.value = !0;
870
+ try {
871
+ let e = await s.uploadFont(await F(n));
872
+ o("change", e);
873
+ } catch (e) {
874
+ w.value = e instanceof Error ? e.message : String(e);
875
+ } finally {
876
+ C.value = !1;
877
+ }
878
+ }
879
+ }
880
+ return (n, a) => i(s) === null ? (t(), p("input", {
881
+ key: 0,
882
+ class: f(["cn-field", i(J)]),
883
+ type: "text",
884
+ value: e.modelValue,
885
+ onInput: m,
886
+ onCompositionstart: h,
887
+ onCompositionend: v,
888
+ onChange: y
889
+ }, null, 42, ct)) : (t(), p("div", lt, [
890
+ x("select", {
891
+ class: f(["cn-field cn-select", i(K)]),
892
+ value: e.modelValue,
893
+ onChange: u
894
+ }, [(t(!0), p(g, null, b(c.value, (e) => (t(), p("option", {
895
+ key: e.value,
896
+ value: e.value
897
+ }, r(e.label), 9, dt))), 128))], 42, ut),
898
+ x("input", {
899
+ ref_key: "fileInput",
900
+ ref: T,
901
+ type: "file",
902
+ class: "hidden",
903
+ accept: ".ttf,.otf,.woff,.woff2,font/ttf,font/otf,font/woff,font/woff2",
904
+ onChange: D
905
+ }, null, 544),
906
+ i(s).canUpload ? (t(), p("button", {
907
+ key: 0,
908
+ type: "button",
909
+ class: "h-7 shrink-0 rounded-md border border-cn-field-line bg-cn-field px-2 text-[11px] leading-none text-cn-fg transition-colors duration-100 hover:border-cn-muted/40 disabled:cursor-not-allowed disabled:opacity-40",
910
+ disabled: C.value,
911
+ title: w.value ?? "上传本机字体(加入清单后可选)",
912
+ "data-upload-error": w.value ?? void 0,
913
+ onClick: E
914
+ }, r(C.value ? "…" : w.value ? "!" : "上传"), 9, ft)) : _("", !0)
915
+ ]));
916
+ }
917
+ }), mt = { class: "cn-color flex min-w-0 flex-1 items-center gap-1.5" }, ht = ["checked"], gt = ["value", "disabled"], _t = ["value", "disabled"], vt = "#000000", yt = /* @__PURE__ */ h({
918
+ __name: "ColorField",
919
+ props: {
920
+ field: {},
921
+ modelValue: {}
922
+ },
923
+ emits: ["input", "change"],
924
+ setup(e, { emit: n }) {
925
+ let r = e, a = n, o = k(r.modelValue !== null), c = k(l(r.modelValue));
926
+ s(() => r.modelValue, (e) => {
927
+ o.value = e !== null, o.value && (c.value = l(e));
928
+ });
929
+ function l(e) {
930
+ return e !== null && /^#[0-9a-fA-F]{6}$/.test(e) ? e : vt;
931
+ }
932
+ function u(e) {
933
+ let t = e.target.checked;
934
+ if (o.value = t, !t) {
935
+ a("change", null);
936
+ return;
937
+ }
938
+ let n = c.value;
939
+ a("change", n);
940
+ }
941
+ function d(e) {
942
+ let t = e.target.value;
943
+ c.value = t, a("input", t);
944
+ }
945
+ function m(e) {
946
+ let t = e.target.value;
947
+ c.value = t, a("change", t);
948
+ }
949
+ function h(e) {
950
+ let t = e.target.value.trim();
951
+ if (t === "") {
952
+ r.field.nullable && a("change", null);
953
+ return;
954
+ }
955
+ c.value = l(t), a("change", t);
956
+ }
957
+ return (n, r) => (t(), p("span", mt, [
958
+ e.field.nullable ? (t(), p("input", {
959
+ key: 0,
960
+ class: "cn-color__toggle size-3.5 shrink-0 cursor-pointer accent-cn-accent",
961
+ type: "checkbox",
962
+ title: "启用颜色",
963
+ checked: o.value,
964
+ onChange: u
965
+ }, null, 40, ht)) : _("", !0),
966
+ x("input", {
967
+ class: f(["cn-color__swatch", i(Xe)]),
968
+ type: "color",
969
+ value: c.value,
970
+ disabled: !o.value,
971
+ onInput: d,
972
+ onChange: m
973
+ }, null, 42, gt),
974
+ x("input", {
975
+ class: f(["cn-color__text min-w-0 flex-1", i(K)]),
976
+ type: "text",
977
+ value: e.modelValue ?? "",
978
+ disabled: !o.value,
979
+ placeholder: "无",
980
+ onChange: h
981
+ }, null, 42, _t)
982
+ ]));
983
+ }
984
+ }), X = Symbol("canvas-image-upload");
985
+ function bt() {
986
+ return d(X, null);
987
+ }
988
+ //#endregion
989
+ //#region src/property-panel/fields/TextField.vue?vue&type=script&setup=true&lang.ts
990
+ var xt = ["value", "placeholder"], Z = /* @__PURE__ */ h({
991
+ __name: "TextField",
992
+ props: {
993
+ field: {},
994
+ modelValue: {}
995
+ },
996
+ emits: ["input", "change"],
997
+ setup(e, { emit: n }) {
998
+ let r = e, a = n, o = !1, s = k(!1);
999
+ function c(e) {
1000
+ return r.field.nonEmpty === !0 ? e.trim() === "" ? (s.value = !0, !0) : (s.value = !1, !1) : !1;
1001
+ }
1002
+ function l(e) {
1003
+ let t = e.target.value;
1004
+ o || e.isComposing || c(t) || a("input", t);
1005
+ }
1006
+ function u() {
1007
+ o = !0;
1008
+ }
1009
+ function d(e) {
1010
+ o = !1;
1011
+ let t = e.target.value;
1012
+ c(t) || a("input", t);
1013
+ }
1014
+ function m(e) {
1015
+ o = !1;
1016
+ let t = e.target.value;
1017
+ c(t) || a("change", t);
1018
+ }
1019
+ return (n, r) => (t(), p("input", {
1020
+ class: f(["cn-field", [i(J), s.value ? "cn-field--invalid" : ""]]),
1021
+ type: "text",
1022
+ value: e.modelValue,
1023
+ placeholder: e.field.placeholder,
1024
+ onInput: l,
1025
+ onCompositionstart: u,
1026
+ onCompositionend: d,
1027
+ onChange: m
1028
+ }, null, 42, xt));
1029
+ }
1030
+ }), St = {
1031
+ key: 0,
1032
+ class: "flex flex-col gap-1.5"
1033
+ }, Ct = [
1034
+ "disabled",
1035
+ "title",
1036
+ "data-upload-error"
1037
+ ], wt = ["src"], Tt = {
1038
+ key: 2,
1039
+ class: "relative"
1040
+ }, Et = { class: "flex items-center gap-1.5" }, Dt = /* @__PURE__ */ h({
1041
+ __name: "ImageSrcField",
1042
+ props: {
1043
+ field: {},
1044
+ modelValue: {},
1045
+ dataMode: {},
1046
+ resourceStatus: {}
1047
+ },
1048
+ emits: ["input", "change"],
1049
+ setup(e, { emit: n }) {
1050
+ let i = e, a = n, o = bt(), s = S(() => o !== null && o.canUpload && i.dataMode !== "expression"), c = S(() => typeof i.modelValue == "string" && i.modelValue !== ""), l = S(() => i.resourceStatus === "pending" ? "装载中" : i.resourceStatus === "failed" ? "失败" : null), u = k(!1), d = k(null), m = k(null);
1051
+ function h() {
1052
+ d.value = null, m.value?.click();
1053
+ }
1054
+ async function g(e) {
1055
+ let t = e.target, n = t.files?.[0];
1056
+ if (t.value = "", o !== null && n && !u.value) {
1057
+ u.value = !0;
1058
+ try {
1059
+ let e = await o.uploadImage(await F(n));
1060
+ e !== null && a("change", e);
1061
+ } catch (e) {
1062
+ d.value = e instanceof Error ? e.message : String(e);
1063
+ } finally {
1064
+ u.value = !1;
1065
+ }
1066
+ }
1067
+ }
1068
+ return (n, i) => s.value ? (t(), p("div", St, [
1069
+ x("button", {
1070
+ type: "button",
1071
+ class: "cn-imagesrc__thumb relative flex h-16 w-full items-center justify-center overflow-hidden rounded-md border border-dashed border-cn-field-line bg-cn-field/40 text-[11px] leading-none text-cn-muted transition-colors duration-100 hover:border-cn-muted/40 disabled:cursor-not-allowed disabled:opacity-40",
1072
+ disabled: u.value,
1073
+ title: d.value ?? (c.value ? "点击替换图片" : "点击上传图片"),
1074
+ "data-upload-error": d.value ?? void 0,
1075
+ onClick: h
1076
+ }, [
1077
+ c.value ? (t(), p("img", {
1078
+ key: 0,
1079
+ src: e.modelValue ?? void 0,
1080
+ class: "absolute inset-0 size-full object-cover",
1081
+ alt: ""
1082
+ }, null, 8, wt)) : _("", !0),
1083
+ l.value ? (t(), p("span", {
1084
+ key: 1,
1085
+ class: f(["cn-imagesrc__status absolute right-1 top-1 rounded bg-cn-bg-elevated/90 px-1 py-0.5 text-[10px] leading-none", e.resourceStatus === "failed" ? "text-red-400" : "text-cn-muted"])
1086
+ }, r(l.value), 3)) : _("", !0),
1087
+ c.value ? _("", !0) : (t(), p("span", Tt, r(u.value ? "…" : d.value ? "!" : "点击上传图片"), 1))
1088
+ ], 8, Ct),
1089
+ x("input", {
1090
+ ref_key: "fileInput",
1091
+ ref: m,
1092
+ type: "file",
1093
+ class: "hidden",
1094
+ accept: "image/*",
1095
+ onChange: g
1096
+ }, null, 544),
1097
+ x("div", Et, [O(Z, {
1098
+ class: "flex-1",
1099
+ field: e.field,
1100
+ "model-value": e.modelValue ?? "",
1101
+ "aria-label": e.field.label,
1102
+ onInput: i[0] ||= (e) => a("input", e),
1103
+ onChange: i[1] ||= (e) => a("change", e)
1104
+ }, null, 8, [
1105
+ "field",
1106
+ "model-value",
1107
+ "aria-label"
1108
+ ]), c.value ? (t(), p("button", {
1109
+ key: 0,
1110
+ type: "button",
1111
+ class: "cn-imagesrc__clear h-7 shrink-0 rounded-md border border-cn-field-line bg-cn-field px-2 text-[11px] leading-none text-cn-fg transition-colors duration-100 hover:border-cn-muted/40",
1112
+ title: "清除图片(资源地址置空)",
1113
+ onClick: i[2] ||= (e) => a("change", "")
1114
+ }, "清除")) : _("", !0)])
1115
+ ])) : (t(), v(Z, {
1116
+ key: 1,
1117
+ field: e.field,
1118
+ "model-value": e.modelValue ?? "",
1119
+ "aria-label": e.field.label,
1120
+ onInput: i[3] ||= (e) => a("input", e),
1121
+ onChange: i[4] ||= (e) => a("change", e)
1122
+ }, null, 8, [
1123
+ "field",
1124
+ "model-value",
1125
+ "aria-label"
1126
+ ]));
1127
+ }
1128
+ }), Ot = [
1129
+ "aria-label",
1130
+ "min",
1131
+ "max",
1132
+ "step"
1133
+ ], Q = /* @__PURE__ */ h({
1134
+ __name: "NumberField",
1135
+ props: {
1136
+ field: {},
1137
+ modelValue: {}
1138
+ },
1139
+ emits: ["input", "change"],
1140
+ setup(e, { emit: r }) {
1141
+ let a = e, o = r, c = k(String(a.modelValue)), l = k(!1);
1142
+ s(() => a.modelValue, (e) => {
1143
+ l.value || (c.value = String(e));
1144
+ });
1145
+ function u(e) {
1146
+ let t = a.field.integer ? Math.trunc(e) : e;
1147
+ return a.field.min !== void 0 && (t = Math.max(a.field.min, t)), a.field.max !== void 0 && (t = Math.min(a.field.max, t)), t;
1148
+ }
1149
+ function d(e) {
1150
+ if (e.value.trim() === "") return null;
1151
+ let t = Number(e.value);
1152
+ return Number.isFinite(t) ? t : null;
1153
+ }
1154
+ function m(e) {
1155
+ let t = e.target;
1156
+ c.value = t.value;
1157
+ let n = d(t);
1158
+ n !== null && o("input", u(n));
1159
+ }
1160
+ function h(e) {
1161
+ let t = d(e.target);
1162
+ if (t === null) {
1163
+ c.value = String(a.modelValue);
1164
+ return;
1165
+ }
1166
+ let n = u(t);
1167
+ c.value = String(n), o("change", n);
1168
+ }
1169
+ return (r, a) => n((t(), p("input", {
1170
+ "onUpdate:modelValue": a[0] ||= (e) => c.value = e,
1171
+ class: f(["cn-field cn-field--number", i(q)]),
1172
+ type: "number",
1173
+ "aria-label": e.field.label,
1174
+ min: e.field.min,
1175
+ max: e.field.max,
1176
+ step: e.field.step ?? (e.field.integer ? 1 : .1),
1177
+ onInput: m,
1178
+ onFocus: a[1] ||= (e) => l.value = !0,
1179
+ onBlur: h,
1180
+ onChange: h
1181
+ }, null, 42, Ot)), [[w, c.value]]);
1182
+ }
1183
+ }), kt = { class: "cn-padding flex w-full min-w-0 items-center gap-1.5" }, At = { class: "w-5 shrink-0 select-none text-[10px] leading-none text-cn-muted" }, jt = /* @__PURE__ */ h({
1184
+ __name: "PaddingField",
1185
+ props: {
1186
+ field: {},
1187
+ modelValue: {}
1188
+ },
1189
+ emits: ["input", "change"],
1190
+ setup(e, { emit: n }) {
1191
+ let a = e, o = n, { mode: s, cycle: c } = G(() => a.modelValue, Ue), l = S(() => U[s.value]);
1192
+ function u(e) {
1193
+ return {
1194
+ key: ["padding", e.rep],
1195
+ label: e.label,
1196
+ control: "number"
1197
+ };
1198
+ }
1199
+ function d(e, t, n) {
1200
+ let r = { ...a.modelValue };
1201
+ for (let n of e.sides) r[n] = t;
1202
+ o(n ? "change" : "input", r);
1203
+ }
1204
+ function m() {
1205
+ let { from: e, to: t } = c();
1206
+ if (t < e) {
1207
+ let e = We(a.modelValue, t);
1208
+ Ge(e, a.modelValue) || o("change", e);
1209
+ }
1210
+ }
1211
+ return (n, a) => (t(), p("span", kt, [O(Y, {
1212
+ mode: i(s),
1213
+ label: "内边距",
1214
+ onCycle: m
1215
+ }, null, 8, ["mode"]), x("span", { class: f(["grid min-w-0 flex-1 gap-1.5", i(s) === 1 ? "grid-cols-1" : "grid-cols-2"]) }, [(t(!0), p(g, null, b(l.value, (n) => (t(), p("label", {
1216
+ key: n.rep,
1217
+ class: "flex min-w-0 items-center gap-1.5"
1218
+ }, [x("span", At, r(n.label), 1), O(Q, {
1219
+ class: "min-w-0 flex-1",
1220
+ field: u(n),
1221
+ "model-value": e.modelValue[n.rep],
1222
+ onInput: (e) => d(n, e, !1),
1223
+ onChange: (e) => d(n, e, !0)
1224
+ }, null, 8, [
1225
+ "field",
1226
+ "model-value",
1227
+ "onInput",
1228
+ "onChange"
1229
+ ])]))), 128))], 2)]));
1230
+ }
1231
+ }), Mt = { class: "grid w-full min-w-0 grid-cols-2 gap-1" }, Nt = ["title"], Pt = { class: "w-3.5 shrink-0 select-none text-[10px] leading-none text-cn-muted" }, Ft = [
1232
+ "aria-pressed",
1233
+ "title",
1234
+ "onClick"
1235
+ ], It = [
1236
+ "aria-label",
1237
+ "value",
1238
+ "placeholder",
1239
+ "title"
1240
+ ], Lt = /* @__PURE__ */ h({
1241
+ __name: "PairField",
1242
+ props: {
1243
+ field: {},
1244
+ modelValue: {},
1245
+ displays: {}
1246
+ },
1247
+ emits: [
1248
+ "input",
1249
+ "change",
1250
+ "sub-commit"
1251
+ ],
1252
+ setup(e, { emit: n }) {
1253
+ let a = e, o = n, s = S(() => a.field.items ?? []);
1254
+ function c(e) {
1255
+ if (!e.auto) return !1;
1256
+ let t = V(a.modelValue, e.auto.key);
1257
+ return t.ok && t.value === !0;
1258
+ }
1259
+ function l(e) {
1260
+ return {
1261
+ ...e,
1262
+ key: z(a.field, e)
1263
+ };
1264
+ }
1265
+ function u(e) {
1266
+ return {
1267
+ key: [...a.field.key, ...e.auto?.key ?? []],
1268
+ label: `${e.label}自适应`,
1269
+ control: "boolean"
1270
+ };
1271
+ }
1272
+ function d(e, t, n) {
1273
+ o("sub-commit", l(e), t, n);
1274
+ }
1275
+ function m(e) {
1276
+ o("sub-commit", u(e), !c(e), !0);
1277
+ }
1278
+ function h(e) {
1279
+ let t = V(a.modelValue, e.key);
1280
+ return t.ok && typeof t.value == "number" ? t.value : 0;
1281
+ }
1282
+ function y(e) {
1283
+ return a.displays?.[z(a.field, e).join(".")];
1284
+ }
1285
+ function C(e) {
1286
+ let t = y(e);
1287
+ return t === void 0 ? "" : String(t.value);
1288
+ }
1289
+ function w(e) {
1290
+ return c(e) ? `${e.label}自适应:已开启(输入框禁用)` : `${e.label}自适应:开启后由内容决定,输入框禁用`;
1291
+ }
1292
+ function E(e) {
1293
+ let t = y(e);
1294
+ return t?.preview ? "模板子树:预览盒尺寸(随行实例变化,非文档声明值)" : t === void 0 ? `${e.label}自适应:已开启` : `${e.label}自适应:布局解析值(与画布选择框同源)`;
1295
+ }
1296
+ return (e, n) => (t(), p("span", Mt, [(t(!0), p(g, null, b(s.value, (e) => (t(), p("label", {
1297
+ key: e.key.join("."),
1298
+ class: "flex min-w-0 items-center gap-1",
1299
+ title: e.auto ? void 0 : e.label
1300
+ }, [
1301
+ x("span", Pt, r(e.label), 1),
1302
+ e.auto ? (t(), p("button", {
1303
+ key: 0,
1304
+ type: "button",
1305
+ class: f(["cn-props__auto-toggle shrink-0", { "cn-props__auto-toggle--active": c(e) }]),
1306
+ "aria-pressed": c(e),
1307
+ title: w(e),
1308
+ onClick: T((t) => m(e), ["prevent"])
1309
+ }, "自", 10, Ft)) : _("", !0),
1310
+ c(e) ? (t(), p("input", {
1311
+ key: 2,
1312
+ class: f(["cn-field cn-field--number min-w-0 flex-1", [i(q), y(e)?.preview ? "cn-field--preview" : ""]]),
1313
+ type: "number",
1314
+ disabled: "",
1315
+ "aria-label": e.label,
1316
+ value: C(e),
1317
+ placeholder: e.auto?.placeholder ?? "",
1318
+ title: E(e)
1319
+ }, null, 10, It)) : (t(), v(Q, {
1320
+ key: 1,
1321
+ class: "min-w-0 flex-1",
1322
+ field: e,
1323
+ "model-value": h(e),
1324
+ onInput: (t) => d(e, t, !1),
1325
+ onChange: (t) => d(e, t, !0)
1326
+ }, null, 8, [
1327
+ "field",
1328
+ "model-value",
1329
+ "onInput",
1330
+ "onChange"
1331
+ ]))
1332
+ ], 8, Nt))), 128))]));
1333
+ }
1334
+ }), Rt = ["value"], zt = ["value"], Bt = /* @__PURE__ */ h({
1335
+ __name: "SelectField",
1336
+ props: {
1337
+ field: {},
1338
+ modelValue: {}
1339
+ },
1340
+ emits: ["change"],
1341
+ setup(e, { emit: n }) {
1342
+ let i = n;
1343
+ function a(e) {
1344
+ i("change", e.target.value);
1345
+ }
1346
+ return (n, i) => (t(), p("select", {
1347
+ class: "cn-select h-7 w-full min-w-0 flex-1 cursor-pointer appearance-none rounded-md border border-cn-field-line bg-cn-field py-0 pl-2 pr-6 text-[11px] leading-none text-cn-fg outline-none transition-[border-color,box-shadow] duration-100 hover:border-cn-muted/40 focus:border-cn-accent/70 focus:ring-[3px] focus:ring-cn-accent/15 disabled:cursor-not-allowed disabled:opacity-40",
1348
+ value: e.modelValue,
1349
+ onChange: a
1350
+ }, [(t(!0), p(g, null, b(e.field.domain ?? [], (e) => (t(), p("option", {
1351
+ key: e,
1352
+ value: e
1353
+ }, r(e), 9, zt))), 128))], 40, Rt));
1354
+ }
1355
+ }), Vt = ["value"], Ht = /* @__PURE__ */ h({
1356
+ __name: "TextareaField",
1357
+ props: {
1358
+ field: {},
1359
+ modelValue: {}
1360
+ },
1361
+ emits: ["input", "change"],
1362
+ setup(e, { emit: n }) {
1363
+ let r = n, a = !1;
1364
+ function o(e) {
1365
+ let t = e.target.value;
1366
+ a || e.isComposing || r("input", t);
1367
+ }
1368
+ function s() {
1369
+ a = !0;
1370
+ }
1371
+ function c(e) {
1372
+ a = !1, r("input", e.target.value);
1373
+ }
1374
+ function l(e) {
1375
+ a = !1, r("change", e.target.value);
1376
+ }
1377
+ return (n, r) => (t(), p("textarea", {
1378
+ class: f(["cn-field", i(Ye)]),
1379
+ rows: "3",
1380
+ value: e.modelValue,
1381
+ onInput: o,
1382
+ onCompositionstart: s,
1383
+ onCompositionend: c,
1384
+ onChange: l
1385
+ }, null, 42, Vt));
1386
+ }
1387
+ }), Ut = {
1388
+ number: a(Q),
1389
+ text: a(Z),
1390
+ textarea: a(Ht),
1391
+ color: a(yt),
1392
+ select: a(Bt),
1393
+ boolean: a(Ve),
1394
+ pair: a(Lt),
1395
+ anchor: a(H),
1396
+ align: a(ke),
1397
+ padding: a(jt),
1398
+ border: a(at),
1399
+ font: a(pt),
1400
+ imageSrc: a(Dt)
1401
+ };
1402
+ //#endregion
1403
+ //#region src/property-panel/usePropertyPanel.ts
1404
+ function $(t) {
1405
+ let n = e(t.store.doc), r = e(t.store.ui.selection), i = e(t.store.ui.anchorExpanded), a = e(t.store.ui.dataSourceSchema), s = e(t.store.ui.resourceStatuses), c = t.subscribe((e) => {
1406
+ e.scope === "doc" ? (n.value = t.store.doc, r.value = t.store.ui.selection, s.value = t.store.ui.resourceStatuses) : e.scope === "ui" && (e.branch === "selection" ? (r.value = t.store.ui.selection, t.store.closeMerge()) : e.branch === "anchorExpanded" ? i.value = t.store.ui.anchorExpanded : e.branch === "dataSourceSchema" ? a.value = t.store.ui.dataSourceSchema : e.branch === "resourceStatuses" && (s.value = t.store.ui.resourceStatuses));
1407
+ });
1408
+ o(c, !0);
1409
+ let l = S(() => {
1410
+ let e = n.value, t = r.value;
1411
+ return e && t ? m(e, t) : null;
1412
+ }), u = S(() => n.value), d = S(() => {
1413
+ let e = l.value, t = r.value;
1414
+ return e && t ? Te(t, e) : n.value ? B : [];
1415
+ }), f = S(() => {
1416
+ let e = r.value;
1417
+ return e && n.value ? t.layerBoxAt(e) : null;
1418
+ }), p = S(() => {
1419
+ let e = a.value;
1420
+ return e === null ? null : fe(e, ue(e, n.value, r.value));
1421
+ }), h = S(() => pe(me(n.value, r.value, a.value))), g = S(() => r.value?.includes("template") ?? !1);
1422
+ function _(e) {
1423
+ t.store.setAnchorExpanded(e);
1424
+ }
1425
+ function v(e) {
1426
+ if (!e.data) return !1;
1427
+ let t = l.value;
1428
+ return t !== null && "expression" in t && t.expression !== null;
1429
+ }
1430
+ function y(e, i, a) {
1431
+ if (!n.value) return;
1432
+ let o = r.value;
1433
+ if (!o) {
1434
+ x(e, i, a);
1435
+ return;
1436
+ }
1437
+ let s = `sel:${o.join(".")}:${e.key.join(".")}`;
1438
+ if (e.data) {
1439
+ if (v(e)) {
1440
+ let e = `sel:${o.join(".")}:data.expression`;
1441
+ t.updateDataExpression(o, i, { mergeKey: e }), a && t.store.closeMerge(e);
1442
+ return;
1443
+ }
1444
+ t.updateData(o, i, { mergeKey: s }), a && t.store.closeMerge(s);
1445
+ return;
1446
+ }
1447
+ t.updateSpec(o, e.key, i, { mergeKey: s }), a && t.store.closeMerge(s);
1448
+ }
1449
+ function b(e) {
1450
+ let n = l.value, i = r.value;
1451
+ if (!n || !i || !e.data) return;
1452
+ let a = V(n, e.key);
1453
+ if (!a.ok) return;
1454
+ let o = typeof a.value == "string" ? a.value : "";
1455
+ v(e) ? t.updateData(i, o) : t.updateDataExpression(i, o);
1456
+ }
1457
+ function x(e, n, r) {
1458
+ let i = e.key[0];
1459
+ if (i !== "width" && i !== "height" || typeof n != "number") return;
1460
+ let a = `canvas:${i}`;
1461
+ t.updateCanvasProp(i, n, { mergeKey: a }), r && t.store.closeMerge(a);
1462
+ }
1463
+ return {
1464
+ selection: S(() => r.value),
1465
+ layer: l,
1466
+ canvas: u,
1467
+ sections: d,
1468
+ layerBox: f,
1469
+ isPreviewBox: g,
1470
+ completionSource: p,
1471
+ rowsPathSource: h,
1472
+ resourceStatuses: S(() => s.value),
1473
+ anchorExpanded: S(() => i.value),
1474
+ commit: y,
1475
+ toggleDataMode: b,
1476
+ setAnchorExpanded: _
1477
+ };
1478
+ }
1479
+ //#endregion
1480
+ //#region src/property-panel/fields/ValueTypeSegmented.vue?vue&type=script&setup=true&lang.ts
1481
+ var Wt = {
1482
+ class: "cn-valuetype flex h-7 shrink-0 items-stretch overflow-hidden rounded-md border border-cn-field-line bg-cn-field",
1483
+ role: "group",
1484
+ "aria-label": "取值方式"
1485
+ }, Gt = [
1486
+ "aria-pressed",
1487
+ "title",
1488
+ "onClick"
1489
+ ], Kt = /* @__PURE__ */ h({
1490
+ __name: "ValueTypeSegmented",
1491
+ props: { mode: {} },
1492
+ emits: ["change"],
1493
+ setup(e, { emit: n }) {
1494
+ let i = e, a = n, o = [{
1495
+ value: "static",
1496
+ label: "静态",
1497
+ title: "静态值:输入的字面内容直接显示在画布上"
1498
+ }, {
1499
+ value: "expression",
1500
+ label: "表达式",
1501
+ title: "表达式值:内容为插值原文,画布显示解析镜像({{路径}} / {{$index}} / {{$root.*}})"
1502
+ }];
1503
+ function s(e) {
1504
+ e !== i.mode && a("change", e);
1505
+ }
1506
+ return (n, i) => (t(), p("span", Wt, [(t(), p(g, null, b(o, (t, n) => x("button", {
1507
+ key: t.value,
1508
+ type: "button",
1509
+ class: f(["cn-valuetype__option flex items-center justify-center p-0 px-1.5 text-[10px] leading-none transition-colors duration-100 focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-cn-accent/40", [n > 0 ? "border-l border-cn-field-line" : "", t.value === e.mode ? "cn-valuetype__option--active bg-cn-accent-soft text-cn-accent" : "text-cn-muted hover:text-cn-fg"]]),
1510
+ "aria-pressed": t.value === e.mode,
1511
+ title: t.value === e.mode ? t.title : `${t.title};点击切换`,
1512
+ onClick: T((e) => s(t.value), ["prevent"])
1513
+ }, r(t.label), 11, Gt)), 64))]));
1514
+ }
1515
+ }), qt = ["title"], Jt = {
1516
+ key: 2,
1517
+ class: "cn-prop-field__hint col-span-2 block text-[11px] leading-4 text-cn-muted"
1518
+ }, Yt = /* @__PURE__ */ h({
1519
+ __name: "PropertyField",
1520
+ props: {
1521
+ field: {},
1522
+ value: {},
1523
+ dataMode: {},
1524
+ completion: { type: [Function, null] },
1525
+ displays: {},
1526
+ hint: {},
1527
+ resourceStatus: {}
1528
+ },
1529
+ emits: [
1530
+ "input",
1531
+ "change",
1532
+ "toggle-mode",
1533
+ "sub-commit"
1534
+ ],
1535
+ setup(e, { emit: n }) {
1536
+ let a = e, o = n, s = S(() => Ut[a.field.control]), c = S(() => a.dataMode === "expression"), l = S(() => a.field.control === "pair" ? "cn-prop-field block" : "cn-prop-field grid grid-cols-[60px_minmax(0,1fr)] items-center gap-x-2 gap-y-1.5"), d = S(() => a.field.data === !0 ? "col-span-2" : ""), m = S(() => a.field.data === !0 && (a.field.control === "textarea" || a.field.control === "text" || a.field.control === "imageSrc")), h = S(() => a.field.completion === "rowsPath"), b = S(() => m.value || h.value), x = k(null), C = S(() => {
1537
+ if (!b.value) return null;
1538
+ let e = x.value?.$el;
1539
+ return e instanceof HTMLTextAreaElement || e instanceof HTMLInputElement ? e : null;
1540
+ }), w = k(null), T = S(() => w.value?.rootEl ?? null), { popup: E, accept: D } = de({
1541
+ target: C,
1542
+ enabled: () => m.value && c.value && a.completion != null,
1543
+ pairing: () => m.value && c.value,
1544
+ resolve: (e) => a.completion?.(e) ?? null,
1545
+ popupEl: T
1546
+ }), { popup: O, accept: A } = he({
1547
+ target: C,
1548
+ enabled: () => h.value && a.completion != null,
1549
+ resolve: (e) => a.completion?.(e) ?? null,
1550
+ popupEl: T
1551
+ });
1552
+ function j(e, t, n) {
1553
+ o("sub-commit", e, t, n);
1554
+ }
1555
+ return (n, a) => (t(), p(g, null, [(t(), v(y(e.field.control === "pair" || e.field.control === "imageSrc" ? "div" : "label"), { class: f(l.value) }, {
1556
+ default: u(() => [
1557
+ e.field.control === "pair" ? _("", !0) : (t(), p("span", {
1558
+ key: 0,
1559
+ class: "cn-prop-field__label shrink-0 select-none truncate text-[11px] leading-none text-cn-muted",
1560
+ title: e.field.title
1561
+ }, r(e.field.label), 9, qt)),
1562
+ e.field.data ? (t(), v(Kt, {
1563
+ key: 1,
1564
+ class: "justify-self-end",
1565
+ mode: e.dataMode ?? "static",
1566
+ onChange: a[0] ||= (e) => o("toggle-mode")
1567
+ }, null, 8, ["mode"])) : _("", !0),
1568
+ (t(), v(y(s.value), {
1569
+ ref_key: "controlRef",
1570
+ ref: x,
1571
+ class: f(["cn-prop-field__control", [d.value, { "cn-field--expression": c.value }]]),
1572
+ field: e.field,
1573
+ "model-value": e.value,
1574
+ displays: e.field.control === "pair" ? e.displays : void 0,
1575
+ "data-mode": e.field.control === "imageSrc" ? e.dataMode : void 0,
1576
+ "resource-status": e.field.control === "imageSrc" ? e.resourceStatus : void 0,
1577
+ onInput: a[1] ||= (e) => o("input", e),
1578
+ onChange: a[2] ||= (e) => o("change", e),
1579
+ onSubCommit: j
1580
+ }, null, 40, [
1581
+ "class",
1582
+ "field",
1583
+ "model-value",
1584
+ "displays",
1585
+ "data-mode",
1586
+ "resource-status"
1587
+ ])),
1588
+ e.hint ? (t(), p("span", Jt, r(e.hint), 1)) : _("", !0)
1589
+ ]),
1590
+ _: 1
1591
+ }, 8, ["class"])), m.value ? (t(), v(le, {
1592
+ key: 0,
1593
+ ref_key: "popupRef",
1594
+ ref: w,
1595
+ state: i(E),
1596
+ onSelect: i(D)
1597
+ }, null, 8, ["state", "onSelect"])) : h.value ? (t(), v(le, {
1598
+ key: 1,
1599
+ ref_key: "popupRef",
1600
+ ref: w,
1601
+ state: i(O),
1602
+ onSelect: i(A)
1603
+ }, null, 8, ["state", "onSelect"])) : _("", !0)], 64));
1604
+ }
1605
+ }), Xt = { class: "cn-props flex w-[288px] shrink-0 flex-col overflow-y-auto rounded-xl border border-cn-line bg-cn-bg text-cn-fg shadow-[0_16px_40px_-12px_rgba(2,6,23,0.55)]" }, Zt = { class: "sticky top-0 z-10 border-b border-cn-line bg-cn-bg-elevated/95 px-3.5 py-2.5 backdrop-blur-sm" }, Qt = { class: "flex items-center gap-2" }, $t = { class: "inline-flex items-center gap-1.5 rounded border border-cn-accent/25 bg-cn-accent-soft px-1.5 py-0.5 font-mono text-[10px] leading-4 text-cn-accent" }, en = { class: "text-[12px] font-medium tracking-wide text-cn-fg/90" }, tn = {
1606
+ key: 0,
1607
+ class: "mx-3.5 my-4 rounded-lg border border-dashed border-cn-line px-3 py-6 text-center text-[11px] leading-5 text-cn-muted"
1608
+ }, nn = { class: "cn-props__section-title mb-2 text-[10px] font-semibold uppercase tracking-[0.16em] text-cn-muted" }, rn = { class: "flex flex-col gap-2" }, an = /* @__PURE__ */ h({
1609
+ __name: "PropertyPanel",
1610
+ props: { editor: {} },
1611
+ setup(e) {
1612
+ let n = e, a = $(n.editor);
1613
+ l(X, {
1614
+ canUpload: n.editor.canUpload,
1615
+ uploadImage: (e) => n.editor.uploadImage(e)
1616
+ });
1617
+ function o(e) {
1618
+ return e.completion === "rowsPath" ? a.rowsPathSource.value : a.completionSource.value;
1619
+ }
1620
+ let s = S(() => a.layer.value !== null), c = S(() => {
1621
+ let e = a.layer.value;
1622
+ return e ? e.type : a.canvas.value ? "Canvas" : "—";
1623
+ });
1624
+ function u(e) {
1625
+ let t = V(e, ["expression"]);
1626
+ return t.ok && t.value !== null ? "expression" : "static";
1627
+ }
1628
+ let d = S(() => {
1629
+ let e = a.layer.value ?? (a.selection.value ? null : a.canvas.value);
1630
+ if (!e) return [];
1631
+ let t = a.selection.value?.join(".") ?? "canvas", n = a.layer.value, r = a.resourceStatuses.value, i = [];
1632
+ for (let o of a.sections.value) {
1633
+ let a = [];
1634
+ for (let i of o.fields) {
1635
+ let o = V(e, i.key);
1636
+ o.ok && a.push({
1637
+ key: `${t}:${i.key.join(".")}`,
1638
+ field: i,
1639
+ value: o.value,
1640
+ dataMode: i.data ? u(e) : void 0,
1641
+ hint: i.hint && n ? i.hint(n, r) ?? void 0 : void 0,
1642
+ resourceStatus: i.control === "imageSrc" && typeof o.value == "string" && o.value !== "" ? r[o.value] : void 0
1643
+ });
1644
+ }
1645
+ a.length > 0 && i.push({
1646
+ title: o.title,
1647
+ fields: a
1648
+ });
1649
+ }
1650
+ return i;
1651
+ }), f = S(() => {
1652
+ let e = {}, t = a.layerBox.value, n = a.layer.value;
1653
+ if (!t || !n) return e;
1654
+ let r = /* @__PURE__ */ new Map();
1655
+ if (n.shape.autoWidth && r.set("autoWidth", Math.round(t.width * 100) / 100), n.shape.autoHeight && r.set("autoHeight", Math.round(t.height * 100) / 100), r.size === 0) return e;
1656
+ for (let t of a.sections.value) for (let n of t.fields) for (let t of n.items ?? []) {
1657
+ let i = t.auto ? r.get(t.auto.key.join(".")) : void 0;
1658
+ i !== void 0 && (e[z(n, t).join(".")] = {
1659
+ value: i,
1660
+ preview: a.isPreviewBox.value
1661
+ });
1662
+ }
1663
+ return e;
1664
+ });
1665
+ function m() {
1666
+ a.setAnchorExpanded(!a.anchorExpanded.value);
1667
+ }
1668
+ return (e, n) => (t(), p("aside", Xt, [
1669
+ x("header", Zt, [x("div", Qt, [x("span", $t, [n[0] ||= x("i", {
1670
+ class: "size-1.5 rounded-full bg-cn-accent",
1671
+ "aria-hidden": "true"
1672
+ }, null, -1), E(" " + r(c.value), 1)]), x("span", en, r(s.value ? "图层属性" : "画布属性"), 1)])]),
1673
+ d.value.length === 0 ? (t(), p("p", tn, " 打开文档后可编辑属性 ")) : _("", !0),
1674
+ (t(!0), p(g, null, b(d.value, (e) => (t(), p("section", {
1675
+ key: e.title,
1676
+ class: "cn-props__section border-b border-cn-line/70 px-3.5 py-3 last:border-b-0"
1677
+ }, [x("h3", nn, r(e.title), 1), x("div", rn, [(t(!0), p(g, null, b(e.fields, (e) => (t(), p(g, { key: e.key }, [e.field.control === "anchor" ? (t(), v(H, {
1678
+ key: 0,
1679
+ field: e.field,
1680
+ "model-value": e.value,
1681
+ expanded: i(a).anchorExpanded.value,
1682
+ onChange: (t) => i(a).commit(e.field, t, !0),
1683
+ onToggle: m
1684
+ }, null, 8, [
1685
+ "field",
1686
+ "model-value",
1687
+ "expanded",
1688
+ "onChange"
1689
+ ])) : (t(), v(Yt, {
1690
+ key: 1,
1691
+ field: e.field,
1692
+ value: e.value,
1693
+ "data-mode": e.dataMode,
1694
+ hint: e.hint,
1695
+ completion: o(e.field),
1696
+ displays: f.value,
1697
+ "resource-status": e.resourceStatus,
1698
+ onInput: (t) => i(a).commit(e.field, t, !1),
1699
+ onChange: (t) => i(a).commit(e.field, t, !0),
1700
+ onToggleMode: (t) => i(a).toggleDataMode(e.field),
1701
+ onSubCommit: i(a).commit
1702
+ }, null, 8, [
1703
+ "field",
1704
+ "value",
1705
+ "data-mode",
1706
+ "hint",
1707
+ "completion",
1708
+ "displays",
1709
+ "resource-status",
1710
+ "onInput",
1711
+ "onChange",
1712
+ "onToggleMode",
1713
+ "onSubCommit"
1714
+ ]))], 64))), 128))])]))), 128))
1715
+ ]));
1716
+ }
1717
+ });
1718
+ //#endregion
1719
+ export { X as a, st as c, Te as d, Se as f, Ut as i, B as l, V as m, Yt as n, bt as o, Ce as p, $ as r, ot as s, an as t, xe as u };