@hankchen/canvas-editor-vue 0.4.0 → 0.5.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.
@@ -1469,10 +1469,10 @@ var ht = ["wrap"], gt = /*#__PURE__*/ x(/* @__PURE__ */ z({
1469
1469
  };
1470
1470
  else if (N.mode === "resize") {
1471
1471
  let t = F(e);
1472
- y.resizeTo(t.x, t.y);
1472
+ y.resizeTo(t.x, t.y, e.shiftKey);
1473
1473
  } else if (N.mode === "create") {
1474
1474
  let t = F(e);
1475
- y.createTo(t.x, t.y);
1475
+ y.createTo(t.x, t.y, e.shiftKey);
1476
1476
  } else {
1477
1477
  let t = F(e);
1478
1478
  y.dragTo(t.x, t.y);
@@ -1626,7 +1626,7 @@ var ht = ["wrap"], gt = /*#__PURE__*/ x(/* @__PURE__ */ z({
1626
1626
  x.value ? (K(), I("div", _t, [...n[0] ||= [L("span", { class: "cn-surface__drop-hint-text" }, "松开以上传图片", -1)]])) : F("", !0)
1627
1627
  ], 6));
1628
1628
  }
1629
- }), [["__scopeId", "data-v-f2b89db2"]]);
1629
+ }), [["__scopeId", "data-v-2327ee46"]]);
1630
1630
  //#endregion
1631
1631
  //#region src/canvas/guideSnap.ts
1632
1632
  function bt(e, t, n, r) {
package/dist/canvas.js CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "./canvas-DqQislJ_.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "./canvas-CX1RdlFC.js";
2
2
  export { e as AlignFloatBar, n as CanvasSurface, a as ContextMenu, f as EditOverlayToolbar, l as FindBar, m as GuidesOverlay, d as Ruler, c as TextEditingOverlay, u as createGizmoOverlayPainter, h as createRafScheduler, t as drawCreateRubberBand, s as drawFindMatches, p as drawSelectionGizmo, r as useDpr, o as useFindSession, g as useTextEditing, i as watchDprChanges };
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "./canvas-DqQislJ_.js";
2
- import { a as _, i as v, n as y, o as b, r as x, s as S, t as C } from "./layer-panel-DskyCgF5.js";
3
- import { a as w, c as T, d as E, f as D, i as O, l as k, n as A, o as j, r as M, s as N, t as P, u as F } from "./property-panel-B32ZBQdf.js";
4
- import { a as I, i as L, n as R, o as z, r as B, s as V, t as H } from "./popupPosition-Ck5Gsvjy.js";
5
- import { c as U, i as W, n as G, s as K, t as q } from "./useTransientFeedback-CTjmMmFF.js";
6
- import { a as J, c as Y, i as X, l as Z, n as Q, o as $, r as ee, s as te, t as ne } from "./uploadFile-D1RY-ji0.js";
7
- import { i as re, n as ie, r as ae, t as oe } from "./resourceTemplate-cdcQtp9a.js";
8
- import { n as se, t as ce } from "./usePathCompletion-Do17CQ6l.js";
9
- import { n as le, t as ue } from "./useViewport-D9Ipevzs.js";
10
- import { n as de, r as fe, t as pe } from "./useDataSourceSchema-CGbldbUj.js";
11
- import { n as me, r as he, t as ge } from "./status-bar-_PvEXyq8.js";
12
- import { t as _e } from "./useShortcutsHelp-CsyarO2P.js";
13
- import { n as ve, r as ye, t as be } from "./shared-wuupBoZg.js";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "./canvas-CX1RdlFC.js";
2
+ import { a as _, c as v, i as y, l as b, n as x, o as S, r as C, s as w, t as T } from "./layer-panel-kOceTf8H.js";
3
+ import { a as E, c as D, d as O, f as k, i as A, l as j, n as M, o as N, r as P, s as F, t as I, u as L } from "./property-panel-B32ZBQdf.js";
4
+ import { a as R, i as z, n as B, o as V, r as H, s as U, t as W } from "./popupPosition-Ck5Gsvjy.js";
5
+ import { c as G, i as K, n as q, s as J, t as Y } from "./useTransientFeedback-CTjmMmFF.js";
6
+ import { a as X, c as Z, i as Q, l as $, n as ee, o as te, r as ne, s as re, t as ie } from "./uploadFile-D1RY-ji0.js";
7
+ import { i as ae, n as oe, r as se, t as ce } from "./resourceTemplate-cdcQtp9a.js";
8
+ import { n as le, t as ue } from "./usePathCompletion-Do17CQ6l.js";
9
+ import { n as de, t as fe } from "./useViewport-D9Ipevzs.js";
10
+ import { n as pe, r as me, t as he } from "./useDataSourceSchema-CGbldbUj.js";
11
+ import { n as ge, r as _e, t as ve } from "./status-bar-_PvEXyq8.js";
12
+ import { t as ye } from "./useShortcutsHelp-CsyarO2P.js";
13
+ import { n as be, r as xe, t as Se } from "./shared-wuupBoZg.js";
14
14
  //#region src/index.ts
15
- var xe = "@hankchen/canvas-editor-vue";
15
+ var Ce = "@hankchen/canvas-editor-vue";
16
16
  //#endregion
17
- export { v as ADD_LAYER_MENU, _ as ADD_MENU, b as ADD_TEXT_PRESET_MENU, W as ARM_LAYER_CREATE_HINT, e as AlignFloatBar, N as CANVAS_FIELD_SECTIONS, n as CanvasSurface, a as ContextMenu, de as DropdownMenu, f as EditOverlayToolbar, z as ExpressionCompletionPopup, ae as ExpressionPathPicker, T as FIELD_SECTIONS_BY_TYPE, ee as FONT_PICKER_KEY, l as FindBar, m as GuidesOverlay, ye as HelpDialog, w as IMAGE_UPLOAD_KEY, C as LayerPanel, xe as PACKAGE_NAME, S as PANEL_ADD_MENU, H as POPUP_GAP, R as POPUP_MARGIN, V as PanelIcon, A as PropertyField, P as PropertyPanel, d as Ruler, ge as StatusBar, c as TextEditingOverlay, I as applyCompletion, oe as attachResourceTemplate, O as controlRegistry, u as createGizmoOverlayPainter, h as createRafScheduler, K as detectShortcutPlatform, t as drawCreateRubberBand, s as drawFindMatches, p as drawSelectionGizmo, Y as expressionCompletionSource, J as expressionDiagnosticHint, Z as expressionFieldContext, k as fieldSectionsForPath, F as fieldSectionsForType, me as formatLayerGeometry, he as formatLayerPath, X as injectFontPicker, j as injectImageUpload, G as isEditableEventTarget, y as isUpperHalf, E as layerRoleAt, L as measureCursorAnchor, re as pathPickerEntries, B as placePopupInViewport, D as readField, se as rowsPathCompletionSource, Q as selectionFieldMergeKey, U as shortcutActionLabel, ie as stripResourceTemplate, ne as uploadFileFromDom, pe as useDataSourceSchema, r as useDpr, fe as useDropdownMenu, te as useExpressionCompletion, $ as useExpressionDiagnostics, o as useFindSession, ve as useHistory, x as useLayerPanel, ce as usePathCompletion, M as usePropertyPanel, le as useSelection, be as useShortcuts, _e as useShortcutsHelp, g as useTextEditing, q as useTransientFeedback, ue as useViewport, i as watchDprChanges };
17
+ export { _ as ADD_LAYER_MENU, S as ADD_MENU, w as ADD_RATIO_PRESET_MENU, v as ADD_TEXT_PRESET_MENU, K as ARM_LAYER_CREATE_HINT, e as AlignFloatBar, F as CANVAS_FIELD_SECTIONS, n as CanvasSurface, a as ContextMenu, pe as DropdownMenu, f as EditOverlayToolbar, V as ExpressionCompletionPopup, se as ExpressionPathPicker, D as FIELD_SECTIONS_BY_TYPE, ne as FONT_PICKER_KEY, l as FindBar, m as GuidesOverlay, xe as HelpDialog, E as IMAGE_UPLOAD_KEY, T as LayerPanel, Ce as PACKAGE_NAME, b as PANEL_ADD_MENU, W as POPUP_GAP, B as POPUP_MARGIN, U as PanelIcon, M as PropertyField, I as PropertyPanel, d as Ruler, ve as StatusBar, y as TemplateTableForm, c as TextEditingOverlay, R as applyCompletion, ce as attachResourceTemplate, A as controlRegistry, u as createGizmoOverlayPainter, h as createRafScheduler, J as detectShortcutPlatform, t as drawCreateRubberBand, s as drawFindMatches, p as drawSelectionGizmo, Z as expressionCompletionSource, X as expressionDiagnosticHint, $ as expressionFieldContext, j as fieldSectionsForPath, L as fieldSectionsForType, ge as formatLayerGeometry, _e as formatLayerPath, Q as injectFontPicker, N as injectImageUpload, q as isEditableEventTarget, x as isUpperHalf, O as layerRoleAt, z as measureCursorAnchor, ae as pathPickerEntries, H as placePopupInViewport, k as readField, le as rowsPathCompletionSource, ee as selectionFieldMergeKey, G as shortcutActionLabel, oe as stripResourceTemplate, ie as uploadFileFromDom, he as useDataSourceSchema, r as useDpr, me as useDropdownMenu, re as useExpressionCompletion, te as useExpressionDiagnostics, o as useFindSession, be as useHistory, C as useLayerPanel, ue as usePathCompletion, P as usePropertyPanel, de as useSelection, Se as useShortcuts, ye as useShortcutsHelp, g as useTextEditing, Y as useTransientFeedback, fe as useViewport, i as watchDprChanges };
@@ -2,31 +2,5 @@ import { EditorSession } from '@hankchen/canvas-editor';
2
2
  type __VLS_Props = {
3
3
  editor: EditorSession;
4
4
  };
5
- declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
6
- rowsPathInputEl: HTMLInputElement;
7
- pathPopupRef: import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{
8
- state: import('..').ExpressionCompletionState;
9
- }> & Readonly<{
10
- onSelect?: ((index: number) => any) | undefined;
11
- }>, {
12
- rootEl: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
13
- }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
14
- select: (index: number) => any;
15
- }, import('vue').PublicProps, {}, false, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {
16
- rootRef: HTMLDivElement;
17
- }, any, import('vue').ComponentProvideOptions, {
18
- P: {};
19
- B: {};
20
- D: {};
21
- C: {};
22
- M: {};
23
- Defaults: {};
24
- }, Readonly<{
25
- state: import('..').ExpressionCompletionState;
26
- }> & Readonly<{
27
- onSelect?: ((index: number) => any) | undefined;
28
- }>, {
29
- rootEl: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
30
- }, {}, {}, {}, {}> | null;
31
- }, HTMLElement>;
5
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLElement>;
32
6
  export default _default;
@@ -0,0 +1,38 @@
1
+ import { EditorSession } from '@hankchen/canvas-editor';
2
+ type __VLS_Props = {
3
+ editor: EditorSession;
4
+ };
5
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
6
+ cancel: () => any;
7
+ confirm: (rowsPath: string) => any;
8
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
9
+ onCancel?: (() => any) | undefined;
10
+ onConfirm?: ((rowsPath: string) => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
12
+ rowsPathInputEl: HTMLInputElement;
13
+ pathPopupRef: import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{
14
+ state: import('..').ExpressionCompletionState;
15
+ }> & Readonly<{
16
+ onSelect?: ((index: number) => any) | undefined;
17
+ }>, {
18
+ rootEl: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
19
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
20
+ select: (index: number) => any;
21
+ }, import('vue').PublicProps, {}, false, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {
22
+ rootRef: HTMLDivElement;
23
+ }, any, import('vue').ComponentProvideOptions, {
24
+ P: {};
25
+ B: {};
26
+ D: {};
27
+ C: {};
28
+ M: {};
29
+ Defaults: {};
30
+ }, Readonly<{
31
+ state: import('..').ExpressionCompletionState;
32
+ }> & Readonly<{
33
+ onSelect?: ((index: number) => any) | undefined;
34
+ }>, {
35
+ rootEl: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
36
+ }, {}, {}, {}, {}> | null;
37
+ }, HTMLDivElement>;
38
+ export default _default;
@@ -1,4 +1,4 @@
1
- import { LayerType, TextPresetId } from '@hankchen/canvas-editor';
1
+ import { LayerType, RatioPresetId, TextPresetId } from '@hankchen/canvas-editor';
2
2
  /** 新增菜单项(spec §2.1):四类图层武装画拉(drag-create 工单 03);模板表带 rowsPath 必填表单 */
3
3
  export type AddMenuKind = {
4
4
  kind: 'layer';
@@ -17,15 +17,27 @@ export type AddTextPresetKind = {
17
17
  label: string;
18
18
  title: string;
19
19
  };
20
+ /** 比例预设项(image-ratio-preset 工单 02,spec 决策 2):面板专用入口——应用即写建层比例槽 + 武装画拉 */
21
+ export type AddRatioPresetKind = {
22
+ kind: 'ratio-preset';
23
+ preset: RatioPresetId;
24
+ label: string;
25
+ title: string;
26
+ };
20
27
  export declare const ADD_MENU: readonly AddMenuKind[];
21
28
  /** 文本预设三项(text-defaults 工单 02,spec 决策 4):从内核 TEXT_PRESETS 派生
22
29
  * (字号单一事实源,内核改档位文案自动跟随),v1 只定字号——字体缺口由新层样式槽补 */
23
30
  export declare const ADD_TEXT_PRESET_MENU: readonly AddTextPresetKind[];
24
- /** 面板「+」完整序(text-defaults 工单 02,spec 决策 5):文本预设三项插在「文本层」之后;
25
- * 工具栏派生视图 ADD_LAYER_MENU 不含预设(预设只属面板) */
26
- export declare const PANEL_ADD_MENU: readonly (AddMenuKind | AddTextPresetKind)[];
31
+ /** 比例预设六档(image-ratio-preset 工单 02,spec 决策 2):从内核 RATIO_PRESETS
32
+ * 派生(比例与顺序单一事实源)。title 带比例说明与画拉提示;Shift 手势瞬时反转
33
+ * 槽态随档位给反向提示——具名档按 Shift 临时自由、自由档按 Shift 临时钳 1:1 */
34
+ export declare const ADD_RATIO_PRESET_MENU: readonly AddRatioPresetKind[];
35
+ /** 面板「+」完整序(text-defaults 工单 02 + image-ratio-preset 工单 02,spec 决策 2/5):
36
+ * 文本预设三项插在「文本层」之后、比例六档平铺在「图片层」之后;工具栏派生视图
37
+ * ADD_LAYER_MENU 不含预设(预设只属面板) */
38
+ export declare const PANEL_ADD_MENU: readonly (AddMenuKind | AddTextPresetKind | AddRatioPresetKind)[];
27
39
  /** 层型项视图(工具栏「+插入▾」消费,editor-top-toolbar 工单 03):ADD_MENU 的
28
- * 四类图层项,模板表项不进工具栏 */
29
- export declare const ADD_LAYER_MENU: readonly Extract<AddMenuKind, {
30
- kind: 'layer';
31
- }>[];
40
+ * 四类图层项。template-table-drag-create 工单 03 起模板表项同序收入(spec 决策
41
+ * 5,四图层项后收尾)——视图 = ADD_MENU 全量恒等派生,工具栏与面板同序同文案;
42
+ * 分发差异(模板表项弹层表单、四图层项直接武装)归消费面(LayerPanel / 宿主) */
43
+ export declare const ADD_LAYER_MENU: readonly AddMenuKind[];
@@ -1,7 +1,10 @@
1
1
  /**
2
- * 图层面板域出口:图层面板组件、订阅切片桥(useLayerPanel)与新增菜单数据面
3
- * (ADD_MENU/ADD_LAYER_MENU——工具栏「+插入▾」同源消费,editor-top-toolbar 工单 03)。
2
+ * 图层面板域出口:图层面板组件、共享模板行路径表单(TemplateTableForm——面板菜单
3
+ * 与工具栏弹层共用,template-table-drag-create 工单 02)、订阅切片桥(useLayerPanel)
4
+ * 与新增菜单数据面(ADD_MENU/ADD_LAYER_MENU——工具栏「+插入▾」同源消费,
5
+ * editor-top-toolbar 工单 03;两族预设清单面板专用,image-ratio-preset 工单 02 起含比例档位)。
4
6
  */
5
7
  export { default as LayerPanel } from './LayerPanel';
8
+ export { default as TemplateTableForm } from './TemplateTableForm';
6
9
  export { isUpperHalf, useLayerPanel, type LayerPanelBinding } from './useLayerPanel';
7
- export { ADD_LAYER_MENU, ADD_MENU, ADD_TEXT_PRESET_MENU, PANEL_ADD_MENU, type AddMenuKind, type AddTextPresetKind, } from './addMenu';
10
+ export { ADD_LAYER_MENU, ADD_MENU, ADD_RATIO_PRESET_MENU, ADD_TEXT_PRESET_MENU, PANEL_ADD_MENU, type AddMenuKind, type AddRatioPresetKind, type AddTextPresetKind, } from './addMenu';
@@ -2,10 +2,10 @@ import { t as e } from "./createLucideIcon-SCvtEGVf.js";
2
2
  import { i as t, r as n, t as r } from "./layerPath-uy2ywyld.js";
3
3
  import { o as i, s as a, u as o } from "./popupPosition-Ck5Gsvjy.js";
4
4
  import { c as s, i as c, s as l, t as u } from "./useTransientFeedback-CTjmMmFF.js";
5
- import { n as ee, t as te } from "./usePathCompletion-Do17CQ6l.js";
6
- import { n as ne, t as re } from "./useDataSourceSchema-CGbldbUj.js";
7
- import { Fragment as d, computed as f, createBlock as ie, createCommentVNode as p, createElementBlock as m, createElementVNode as h, createVNode as g, defineComponent as _, nextTick as ae, normalizeClass as v, normalizeStyle as oe, onScopeDispose as y, openBlock as b, ref as x, renderList as se, shallowRef as S, toDisplayString as ce, unref as C, vModelText as w, watch as le, withCtx as T, withDirectives as E, withKeys as D, withModifiers as O } from "vue";
8
- var ue = e({
5
+ import { n as d, t as f } from "./usePathCompletion-Do17CQ6l.js";
6
+ import { n as p, t as m } from "./useDataSourceSchema-CGbldbUj.js";
7
+ import { Fragment as h, computed as g, createBlock as _, createCommentVNode as v, createElementBlock as y, createElementVNode as b, createVNode as x, defineComponent as S, nextTick as ee, normalizeClass as C, normalizeStyle as te, onScopeDispose as ne, openBlock as w, ref as T, renderList as re, shallowRef as E, toDisplayString as D, unref as O, vModelText as k, watch as ie, withCtx as A, withDirectives as j, withKeys as ae, withModifiers as M } from "vue";
8
+ var oe = e({
9
9
  name: "eye-off",
10
10
  size: 24,
11
11
  node: [
@@ -26,7 +26,7 @@ var ue = e({
26
26
  key: "1ooewy"
27
27
  }]
28
28
  ]
29
- }), de = e({
29
+ }), se = e({
30
30
  name: "eye",
31
31
  size: 24,
32
32
  node: [["path", {
@@ -38,7 +38,7 @@ var ue = e({
38
38
  r: "3",
39
39
  key: "1v7zrd"
40
40
  }]]
41
- }), fe = e({
41
+ }), ce = e({
42
42
  name: "grip-vertical",
43
43
  size: 24,
44
44
  node: [
@@ -79,7 +79,7 @@ var ue = e({
79
79
  key: "f4zoj3"
80
80
  }]
81
81
  ]
82
- }), pe = e({
82
+ }), le = e({
83
83
  name: "lock-open",
84
84
  size: 24,
85
85
  node: [["rect", {
@@ -95,7 +95,7 @@ var ue = e({
95
95
  key: "1mm8w8"
96
96
  }]],
97
97
  aliases: ["unlock"]
98
- }), me = e({
98
+ }), ue = e({
99
99
  name: "lock",
100
100
  size: 24,
101
101
  node: [["rect", {
@@ -110,7 +110,7 @@ var ue = e({
110
110
  d: "M7 11V7a5 5 0 0 1 10 0v4",
111
111
  key: "fwvmzm"
112
112
  }]]
113
- }), he = e({
113
+ }), de = e({
114
114
  name: "pencil",
115
115
  size: 24,
116
116
  node: [["path", {
@@ -123,7 +123,7 @@ var ue = e({
123
123
  });
124
124
  //#endregion
125
125
  //#region ../canvas-editor/src/editing/layerPanel.ts
126
- function k(e) {
126
+ function N(e) {
127
127
  switch (e.type) {
128
128
  case "TableLayer": return e.template === null ? [{
129
129
  key: "rows",
@@ -149,7 +149,7 @@ function k(e) {
149
149
  }];
150
150
  }
151
151
  }
152
- function A(e) {
152
+ function P(e) {
153
153
  switch (e.type) {
154
154
  case "TextLayer":
155
155
  case "ImageLayer":
@@ -157,22 +157,22 @@ function A(e) {
157
157
  default: return null;
158
158
  }
159
159
  }
160
- var j = "{{…}}";
161
- function M(e) {
162
- let t = A(e);
160
+ var F = "{{…}}";
161
+ function I(e) {
162
+ let t = P(e);
163
163
  if (t === null) return "";
164
164
  let n = o(t).parts.flatMap((e) => e.kind === "fragment" && e.expr !== "" ? [e.expr] : []);
165
- return n.length === 0 ? j : n.map((e) => `{{${e}}}`).join(" ");
165
+ return n.length === 0 ? F : n.map((e) => `{{${e}}}`).join(" ");
166
166
  }
167
- function N(e, t, n, i) {
167
+ function L(e, t, n, i) {
168
168
  let a = [];
169
- for (let { key: n, layers: r } of k(e)) for (let e = 0; e < r.length; e += 1) {
169
+ for (let { key: n, layers: r } of N(e)) for (let e = 0; e < r.length; e += 1) {
170
170
  let o = n === "rows" ? "row" : n === "cells" ? "cell" : n === "template" ? "templateRow" : "content", s = n === "content" ? [...t, "content"] : n === "template" ? [...t, "template"] : [
171
171
  ...t,
172
172
  n,
173
173
  e
174
174
  ];
175
- a.push(N(r[e], s, o, i));
175
+ a.push(L(r[e], s, o, i));
176
176
  }
177
177
  return {
178
178
  type: e.type,
@@ -181,17 +181,17 @@ function N(e, t, n, i) {
181
181
  name: e.name,
182
182
  visible: e.visible,
183
183
  locked: r(t, i),
184
- expressionPrefix: M(e),
184
+ expressionPrefix: I(e),
185
185
  ...e.type === "TableLayer" ? { templated: e.template !== null } : null,
186
186
  children: a
187
187
  };
188
188
  }
189
- function P(e, t = []) {
189
+ function R(e, t = []) {
190
190
  let n = [];
191
- for (let r = e.layers.length - 1; r >= 0; --r) n.push(N(e.layers[r], ["layers", r], "root", t));
191
+ for (let r = e.layers.length - 1; r >= 0; --r) n.push(L(e.layers[r], ["layers", r], "root", t));
192
192
  return n;
193
193
  }
194
- var F = [
194
+ var z = [
195
195
  {
196
196
  id: "heading",
197
197
  fontSize: 40
@@ -204,7 +204,47 @@ var F = [
204
204
  id: "body",
205
205
  fontSize: 16
206
206
  }
207
- ], I = [
207
+ ], B = [
208
+ {
209
+ id: "free",
210
+ ratio: null
211
+ },
212
+ {
213
+ id: "1:1",
214
+ ratio: {
215
+ w: 1,
216
+ h: 1
217
+ }
218
+ },
219
+ {
220
+ id: "4:3",
221
+ ratio: {
222
+ w: 4,
223
+ h: 3
224
+ }
225
+ },
226
+ {
227
+ id: "3:4",
228
+ ratio: {
229
+ w: 3,
230
+ h: 4
231
+ }
232
+ },
233
+ {
234
+ id: "16:9",
235
+ ratio: {
236
+ w: 16,
237
+ h: 9
238
+ }
239
+ },
240
+ {
241
+ id: "9:16",
242
+ ratio: {
243
+ w: 9,
244
+ h: 16
245
+ }
246
+ }
247
+ ], V = [
208
248
  {
209
249
  kind: "layer",
210
250
  type: "TextLayer",
@@ -234,52 +274,131 @@ var F = [
234
274
  label: "模板表",
235
275
  title: "新增模板表(行模板 + 数据行展开)"
236
276
  }
237
- ], L = {
277
+ ], H = {
238
278
  heading: "标题",
239
279
  subheading: "副标题",
240
280
  body: "正文"
241
- }, R = F.map(({ id: e, fontSize: t }) => ({
281
+ }, U = z.map(({ id: e, fontSize: t }) => ({
242
282
  kind: "text-preset",
243
283
  preset: e,
244
- label: L[e],
245
- title: `画拉建${L[e]}文本层(字号 ${t},点击后在画布拖拽定落位与尺寸,Esc 取消)`
246
- })), z = (() => {
247
- let e = I.findIndex((e) => e.kind === "layer" && e.type === "TextLayer");
284
+ label: H[e],
285
+ title: `画拉建${H[e]}文本层(字号 ${t},点击后在画布拖拽定落位与尺寸,Esc 取消)`
286
+ })), W = {
287
+ free: "自由",
288
+ "1:1": "1:1",
289
+ "4:3": "4:3",
290
+ "3:4": "3:4",
291
+ "16:9": "16:9",
292
+ "9:16": "9:16"
293
+ };
294
+ function G(e) {
295
+ return e === null ? "任意宽高" : e.w === e.h ? "正方形" : e.w > e.h ? "横向" : "纵向";
296
+ }
297
+ var K = B.map(({ id: e, ratio: t }) => ({
298
+ kind: "ratio-preset",
299
+ preset: e,
300
+ label: W[e],
301
+ title: e === "free" ? "画拉建自由比例图片层(任意宽高,画拉中按住 Shift 临时锁 1:1;点击后在画布拖拽定落位与尺寸,Esc 取消)" : `画拉建 ${e} 图片层(${G(t)},画拉中按住 Shift 临时自由;点击后在画布拖拽定落位与尺寸,Esc 取消)`
302
+ }));
303
+ function q(e, t, n) {
304
+ let r = e.findIndex(n);
248
305
  return [
249
- ...I.slice(0, e + 1),
250
- ...R,
251
- ...I.slice(e + 1)
306
+ ...e.slice(0, r + 1),
307
+ ...t,
308
+ ...e.slice(r + 1)
252
309
  ];
253
- })(), B = I.filter((e) => e.kind === "layer");
310
+ }
311
+ var J = (e) => (t) => t.kind === "layer" && t.type === e, Y = q(q(V, U, J("TextLayer")), K, J("ImageLayer")), fe = V, pe = {
312
+ key: 0,
313
+ class: "px-2 pb-1 text-[11px] text-cn-danger"
314
+ }, me = { class: "flex gap-1 p-1" }, he = /* @__PURE__ */ S({
315
+ __name: "TemplateTableForm",
316
+ props: { editor: {} },
317
+ emits: ["confirm", "cancel"],
318
+ setup(e, { emit: t }) {
319
+ let n = e, r = t, a = T(""), o = T(!1);
320
+ function s() {
321
+ let e = a.value.trim();
322
+ if (e === "") {
323
+ o.value = !0;
324
+ return;
325
+ }
326
+ r("confirm", e);
327
+ }
328
+ let c = m(n.editor), l = g(() => d(c.value)), u = T(null), p = T(null), { popup: h, accept: _ } = f({
329
+ target: u,
330
+ enabled: () => !0,
331
+ resolve: (e) => l.value?.(e) ?? null,
332
+ popupEl: g(() => p.value?.rootEl ?? null)
333
+ });
334
+ function S(e) {
335
+ if (e.key === "Enter") {
336
+ if (h.open && h.items.length > 0) return;
337
+ e.preventDefault(), s();
338
+ return;
339
+ }
340
+ e.key === "Escape" && (h.open ? e.stopPropagation() : r("cancel"));
341
+ }
342
+ return (e, t) => (w(), y("div", null, [
343
+ t[3] ||= b("p", { class: "px-2 pt-1 text-[11px] leading-4 text-cn-muted" }, "模板行按数据行路径展开成表", -1),
344
+ j(b("input", {
345
+ ref_key: "rowsPathInputEl",
346
+ ref: u,
347
+ "onUpdate:modelValue": t[0] ||= (e) => a.value = e,
348
+ "data-template-rows-path": "",
349
+ type: "text",
350
+ placeholder: "如 order.items",
351
+ class: C(["mx-1 my-1 w-[calc(100%-8px)] rounded border bg-cn-field px-2 py-1 text-[12px] text-cn-fg outline-none focus:border-cn-accent/60", o.value ? "border-cn-danger" : "border-cn-field-line"]),
352
+ onInput: t[1] ||= (e) => o.value = !1,
353
+ onKeydown: S
354
+ }, null, 34), [[k, a.value]]),
355
+ o.value ? (w(), y("p", pe, "rowsPath 必填")) : v("", !0),
356
+ b("div", me, [b("button", {
357
+ type: "button",
358
+ "data-template-confirm": "",
359
+ class: "flex-1 rounded bg-cn-accent/20 px-2 py-1 text-[12px] text-cn-accent hover:bg-cn-accent/30",
360
+ onClick: s
361
+ }, " 创建 "), b("button", {
362
+ type: "button",
363
+ "data-template-cancel": "",
364
+ class: "flex-1 rounded px-2 py-1 text-[12px] text-cn-muted hover:text-cn-fg",
365
+ onClick: t[2] ||= (e) => r("cancel")
366
+ }, " 取消 ")]),
367
+ x(i, {
368
+ ref_key: "pathPopupRef",
369
+ ref: p,
370
+ state: O(h),
371
+ onSelect: O(_)
372
+ }, null, 8, ["state", "onSelect"])
373
+ ]));
374
+ }
375
+ });
254
376
  //#endregion
255
377
  //#region src/layer-panel/useLayerPanel.ts
256
- function V(e) {
257
- let t = S(e.store.doc), n = S(e.store.ui.selection), r = S(e.store.ui.hovered), i = S(e.store.ui.renaming), a = S(e.store.ui.lockedPaths), o = e.subscribe((o) => {
378
+ function ge(e) {
379
+ let t = E(e.store.doc), n = E(e.store.ui.selection), r = E(e.store.ui.hovered), i = E(e.store.ui.renaming), a = E(e.store.ui.lockedPaths), o = e.subscribe((o) => {
258
380
  o.scope === "doc" ? (t.value = e.store.doc, n.value = e.store.ui.selection, r.value = e.store.ui.hovered, i.value = e.store.ui.renaming, a.value = e.store.ui.lockedPaths) : o.branch === "selection" ? n.value = e.store.ui.selection : o.branch === "hovered" ? r.value = e.store.ui.hovered : o.branch === "renaming" ? i.value = e.store.ui.renaming : o.branch === "lockedPaths" && (a.value = e.store.ui.lockedPaths);
259
381
  });
260
- return y(o, !0), {
261
- outline: f(() => t.value ? P(t.value, a.value) : []),
262
- selection: f(() => n.value),
263
- hovered: f(() => r.value),
264
- renaming: f(() => i.value)
382
+ return ne(o, !0), {
383
+ outline: g(() => t.value ? R(t.value, a.value) : []),
384
+ selection: g(() => n.value),
385
+ hovered: g(() => r.value),
386
+ renaming: g(() => i.value)
265
387
  };
266
388
  }
267
- function H(e, t) {
389
+ function _e(e, t) {
268
390
  return t > 0 && e < t / 2;
269
391
  }
270
392
  //#endregion
271
393
  //#region src/layer-panel/LayerPanel.vue?vue&type=script&setup=true&lang.ts
272
- var ge = { class: "cn-props flex w-[232px] 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)]" }, _e = { class: "sticky top-0 z-10 flex items-center justify-between border-b border-cn-line bg-cn-bg-elevated/95 px-3.5 py-2.5" }, ve = { class: "flex items-center gap-1" }, ye = [
394
+ var ve = { class: "cn-props flex w-[232px] 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)]" }, ye = { class: "sticky top-0 z-10 flex items-center justify-between border-b border-cn-line bg-cn-bg-elevated/95 px-3.5 py-2.5" }, be = { class: "flex items-center gap-1" }, xe = [
273
395
  "aria-expanded",
274
396
  "onClick",
275
397
  "onKeydown"
276
- ], be = ["onKeydown"], xe = {
277
- key: 0,
278
- class: "px-2 pb-1 text-[11px] text-cn-danger"
279
- }, Se = { class: "flex gap-1 p-1" }, Ce = ["onClick"], we = ["onClick"], Te = {
398
+ ], Se = {
280
399
  key: 0,
281
400
  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"
282
- }, Ee = [
401
+ }, Ce = [
283
402
  "data-key",
284
403
  "draggable",
285
404
  "onClick",
@@ -287,31 +406,27 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
287
406
  "onDragstart",
288
407
  "onDragover",
289
408
  "onDrop"
290
- ], De = ["onDragstart"], Oe = ["title"], ke = ["onDblclick"], Ae = [
409
+ ], we = ["onDragstart"], Te = ["title"], Ee = ["onDblclick"], De = [
291
410
  "title",
292
411
  "aria-pressed",
293
412
  "onClick"
294
- ], je = [
413
+ ], Oe = [
295
414
  "title",
296
415
  "aria-pressed",
297
416
  "onClick"
298
- ], Me = ["onClick"], Ne = [
417
+ ], ke = ["onClick"], Ae = [
299
418
  "disabled",
300
419
  "title",
301
420
  "onClick"
302
- ], Pe = ["onClick"], Fe = ["onClick"], Ie = [
421
+ ], je = ["onClick"], Me = ["onClick"], Ne = [
303
422
  "disabled",
304
423
  "title",
305
424
  "onClick"
306
- ], U = /* @__PURE__ */ _({
425
+ ], X = /* @__PURE__ */ S({
307
426
  __name: "LayerPanel",
308
427
  props: { editor: {} },
309
428
  setup(e) {
310
- let r = e, o = `解锁图层(${s("toggleLayerLock", l())})`, _ = `图层已锁定(${s("toggleLayerLock", l())} 解锁后可删除)`, y = V(r.editor), S = x(!1), k = x(""), A = x(!1);
311
- function j() {
312
- S.value = !1, k.value = "", A.value = !1;
313
- }
314
- let M = f(() => S.value ? [] : z.map((e) => e.kind === "layer" ? {
429
+ let r = e, i = `解锁图层(${s("toggleLayerLock", l())})`, o = `图层已锁定(${s("toggleLayerLock", l())} 解锁后可删除)`, d = ge(r.editor), f = T(!1), m = g(() => f.value ? [] : Y.map((e) => e.kind === "layer" ? {
315
430
  label: e.label,
316
431
  title: e.title,
317
432
  dataAttrs: { "data-add-layer": e.type },
@@ -328,44 +443,35 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
328
443
  run: () => {
329
444
  r.editor.armLayerCreate("TextLayer", e.preset), u().show(c);
330
445
  }
446
+ } : e.kind === "ratio-preset" ? {
447
+ label: e.label,
448
+ title: e.title,
449
+ dataAttrs: {
450
+ "data-add-layer": "ImageLayer",
451
+ "data-ratio-preset": e.preset
452
+ },
453
+ run: () => {
454
+ r.editor.armLayerCreate("ImageLayer", e.preset), u().show(c);
455
+ }
331
456
  } : {
332
457
  label: e.label,
333
458
  title: e.title,
334
459
  dataAttrs: { "data-add-layer": "template-table" },
335
460
  keepsOpen: !0,
336
461
  run: () => {
337
- S.value = !0;
462
+ f.value = !0;
338
463
  }
339
464
  }));
340
- function N(e) {
341
- let t = k.value.trim();
342
- if (t === "") {
343
- A.value = !0;
344
- return;
345
- }
346
- r.editor.addTemplateTable(t), j(), e();
347
- }
348
- function P(e) {
349
- j(), e();
465
+ function S(e, t) {
466
+ r.editor.armTemplateTableCreate(e), u().show(c), t();
350
467
  }
351
- function F() {
352
- j();
468
+ function ne(e) {
469
+ f.value = !1, e();
353
470
  }
354
- let I = re(r.editor), L = f(() => ee(I.value)), R = x(null), B = x(null), { popup: U, accept: Le } = te({
355
- target: R,
356
- enabled: () => S.value,
357
- resolve: (e) => L.value?.(e) ?? null,
358
- popupEl: f(() => B.value?.rootEl ?? null)
359
- });
360
- function Re(e, t) {
361
- if (e.key === "Enter") {
362
- if (U.open && U.items.length > 0) return;
363
- e.preventDefault(), N(t);
364
- return;
365
- }
366
- e.key === "Escape" && U.open && e.stopPropagation();
471
+ function E() {
472
+ f.value = !1;
367
473
  }
368
- function ze(e, t) {
474
+ function N(e, t) {
369
475
  switch (e.role) {
370
476
  case "root": return e.name === "" ? `${e.type} ${t}` : e.name;
371
477
  case "row": return `行 ${Number(e.path[e.path.length - 1]) + 1}`;
@@ -374,7 +480,7 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
374
480
  case "content": return e.type;
375
481
  }
376
482
  }
377
- let W = f(() => {
483
+ let P = g(() => {
378
484
  let e = [], t = /* @__PURE__ */ new Map();
379
485
  function r(i, a, o, s) {
380
486
  let c = i.role === "row" ? i.path.slice(0, -2) : i.role === "templateRow" ? i.path.slice(0, -1) : s, l = 0;
@@ -382,42 +488,42 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
382
488
  key: i.path.join("."),
383
489
  node: i,
384
490
  indentLevel: a,
385
- label: ze(i, l),
491
+ label: N(i, l),
386
492
  indexInGroup: o,
387
493
  tablePath: c,
388
494
  inTemplate: n(i.path),
389
495
  draggable: i.role === "root" || i.role === "row" || i.role === "cell"
390
496
  }), i.children.forEach((e, t) => r(e, a + 1, t, c));
391
497
  }
392
- return y.outline.value.forEach((e, t) => r(e, 0, t, null)), e;
393
- }), Be = f(() => W.value.length > 0);
394
- function Ve(e) {
498
+ return d.outline.value.forEach((e, t) => r(e, 0, t, null)), e;
499
+ }), F = g(() => P.value.length > 0);
500
+ function I(e) {
395
501
  r.editor.setSelection(e.node.path);
396
502
  }
397
- function G(e) {
503
+ function L(e) {
398
504
  r.editor.setHovered(e === null ? null : e.node.path);
399
505
  }
400
- function He(e) {
506
+ function R(e) {
401
507
  r.editor.addTableRow(e.node.path);
402
508
  }
403
- function Ue(e) {
509
+ function z(e) {
404
510
  r.editor.addTableCell(e.node.path);
405
511
  }
406
- function We(e) {
512
+ function B(e) {
407
513
  r.editor.addTemplateCell(e.node.path.slice(0, -1));
408
514
  }
409
- function Ge(e) {
515
+ function V(e) {
410
516
  r.editor.deleteLayer(e.node.path);
411
517
  }
412
- function Ke(e) {
518
+ function H(e) {
413
519
  r.editor.toggleLayerVisibility(e.node.path);
414
520
  }
415
- function qe(e) {
521
+ function U(e) {
416
522
  r.editor.toggleLayerLock(e.node.path);
417
523
  }
418
- let K = x(null), q = x(null);
419
- function J(e) {
420
- let r = K.value;
524
+ let W = T(null), G = T(null);
525
+ function K(e) {
526
+ let r = W.value;
421
527
  if (!r) return !1;
422
528
  if (r.kind === "root") return e.node.role === "root";
423
529
  if (r.kind === "row") return e.node.role === "row";
@@ -425,11 +531,11 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
425
531
  let i = n(r.cellPath);
426
532
  return i === e.inTemplate ? !i || t(r.cellPath.slice(0, -2), e.node.path.slice(0, -2)) : !1;
427
533
  }
428
- function Y(e) {
534
+ function q(e) {
429
535
  return e.node.role === "root";
430
536
  }
431
- function X(e, t) {
432
- e.draggable && (K.value = e.node.role === "root" ? {
537
+ function J(e, t) {
538
+ e.draggable && (W.value = e.node.role === "root" ? {
433
539
  kind: "root",
434
540
  from: e.indexInGroup
435
541
  } : e.node.role === "row" ? {
@@ -443,74 +549,74 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
443
549
  cellPath: e.node.path
444
550
  }, t.dataTransfer?.setData("text/plain", e.key), t.dataTransfer && (t.dataTransfer.effectAllowed = "move"));
445
551
  }
446
- function Je(e, t) {
447
- Y(e) || X(e, t);
552
+ function fe(e, t) {
553
+ q(e) || J(e, t);
448
554
  }
449
- function Ye(e) {
450
- if (!Y(e)) return e.draggable || void 0;
555
+ function pe(e) {
556
+ if (!q(e)) return e.draggable || void 0;
451
557
  }
452
- function Xe(e, t) {
453
- if (!J(e)) return;
454
- let n = t.currentTarget.getBoundingClientRect(), r = H(t.clientY - n.top, n.height);
455
- t.preventDefault(), q.value = {
558
+ function me(e, t) {
559
+ if (!K(e)) return;
560
+ let n = t.currentTarget.getBoundingClientRect(), r = _e(t.clientY - n.top, n.height);
561
+ t.preventDefault(), G.value = {
456
562
  key: e.key,
457
563
  edge: r ? "before" : "after"
458
564
  };
459
565
  }
460
- function Ze(e, t) {
461
- if (!J(e)) return;
462
- let n = q.value, i = K.value;
566
+ function X(e, t) {
567
+ if (!K(e)) return;
568
+ let n = G.value, i = W.value;
463
569
  if (!i || !n || n.key !== e.key) return;
464
570
  t.preventDefault();
465
571
  let a = n.edge === "before" ? e.indexInGroup : e.indexInGroup + 1;
466
- i.kind === "root" ? r.editor.moveRootLayer(i.from, a) : i.kind === "row" ? e.tablePath !== null && e.tablePath.join(".") === i.tablePath.join(".") ? r.editor.moveTableRow(i.tablePath, i.from, a) : r.editor.moveTableRowToTable(i.rowPath, e.tablePath, a) : r.editor.moveTableCellToRow(i.cellPath, e.node.path.slice(0, -2), a), K.value = null, q.value = null;
572
+ i.kind === "root" ? r.editor.moveRootLayer(i.from, a) : i.kind === "row" ? e.tablePath !== null && e.tablePath.join(".") === i.tablePath.join(".") ? r.editor.moveTableRow(i.tablePath, i.from, a) : r.editor.moveTableRowToTable(i.rowPath, e.tablePath, a) : r.editor.moveTableCellToRow(i.cellPath, e.node.path.slice(0, -2), a), W.value = null, G.value = null;
467
573
  }
468
- function Qe() {
469
- K.value = null, q.value = null;
574
+ function Pe() {
575
+ W.value = null, G.value = null;
470
576
  }
471
- function Z(e) {
472
- return t(y.selection.value, e.node.path);
577
+ function Fe(e) {
578
+ return t(d.selection.value, e.node.path);
473
579
  }
474
- function $e(e) {
475
- return t(y.hovered.value, e.node.path);
580
+ function Ie(e) {
581
+ return t(d.hovered.value, e.node.path);
476
582
  }
477
- let Q = x(""), $ = null, et = null;
478
- function tt(e) {
479
- et = e instanceof HTMLInputElement ? e : null;
583
+ let Z = T(""), Q = null, Le = null;
584
+ function Re(e) {
585
+ Le = e instanceof HTMLInputElement ? e : null;
480
586
  }
481
- function nt(e) {
482
- return t(y.renaming.value, e.node.path);
587
+ function ze(e) {
588
+ return t(d.renaming.value, e.node.path);
483
589
  }
484
- function rt(e) {
485
- Y(e) && r.editor.beginRename(e.node.path);
590
+ function Be(e) {
591
+ q(e) && r.editor.beginRename(e.node.path);
486
592
  }
487
- function it() {
488
- let e = Q.value.trim();
489
- if ($ !== null && e === $.trim()) {
593
+ function $() {
594
+ let e = Z.value.trim();
595
+ if (Q !== null && e === Q.trim()) {
490
596
  r.editor.cancelRename();
491
597
  return;
492
598
  }
493
599
  r.editor.commitRename(e);
494
600
  }
495
- function at() {
601
+ function Ve() {
496
602
  r.editor.cancelRename();
497
603
  }
498
- return le(y.renaming, async (e) => {
604
+ return ie(d.renaming, async (e) => {
499
605
  if (e === null) {
500
- $ = null;
606
+ Q = null;
501
607
  return;
502
608
  }
503
- let n = W.value.find((n) => t(n.node.path, e));
504
- Q.value = n?.label ?? "", $ = Q.value, await ae();
505
- let r = et;
609
+ let n = P.value.find((n) => t(n.node.path, e));
610
+ Z.value = n?.label ?? "", Q = Z.value, await ee();
611
+ let r = Le;
506
612
  r && (r.focus({ preventScroll: !0 }), r.select());
507
- }), (e, t) => (b(), m("aside", ge, [
508
- h("header", _e, [t[9] ||= h("span", { class: "text-[12px] font-medium tracking-wide text-cn-fg/90" }, "图层", -1), h("div", ve, [g(ne, {
613
+ }), (e, t) => (w(), y("aside", ve, [
614
+ b("header", ye, [t[7] ||= b("span", { class: "text-[12px] font-medium tracking-wide text-cn-fg/90" }, "图层", -1), b("div", be, [x(p, {
509
615
  label: "新增图层",
510
- items: M.value,
511
- onClosed: F
616
+ items: m.value,
617
+ onClosed: E
512
618
  }, {
513
- trigger: T(({ open: e, toggle: t, triggerRef: n, onKeydown: r }) => [h("button", {
619
+ trigger: A(({ open: e, toggle: t, triggerRef: n, onKeydown: r }) => [b("button", {
514
620
  ref: n,
515
621
  type: "button",
516
622
  "data-add-menu": "",
@@ -520,171 +626,151 @@ var ge = { class: "cn-props flex w-[232px] shrink-0 flex-col overflow-y-auto rou
520
626
  class: "flex size-6 items-center justify-center rounded border border-cn-field-line bg-cn-field text-[13px] leading-none text-cn-fg/80 hover:border-cn-accent/40 hover:text-cn-accent",
521
627
  onClick: t,
522
628
  onKeydown: r
523
- }, " + ", 40, ye)]),
524
- body: T(({ closeMenu: e }) => [S.value ? (b(), m(d, { key: 0 }, [
525
- t[8] ||= h("p", { class: "px-2 pt-1 text-[11px] leading-4 text-cn-muted" }, "模板行按数据行路径展开成表", -1),
526
- E(h("input", {
527
- ref_key: "rowsPathInputEl",
528
- ref: R,
529
- "onUpdate:modelValue": t[0] ||= (e) => k.value = e,
530
- "data-template-rows-path": "",
531
- type: "text",
532
- placeholder: "如 order.items",
533
- class: v(["mx-1 my-1 w-[calc(100%-8px)] rounded border bg-cn-field px-2 py-1 text-[12px] text-cn-fg outline-none focus:border-cn-accent/60", A.value ? "border-cn-danger" : "border-cn-field-line"]),
534
- onKeydown: (t) => Re(t, e)
535
- }, null, 42, be), [[w, k.value]]),
536
- A.value ? (b(), m("p", xe, "rowsPath 必填")) : p("", !0),
537
- h("div", Se, [h("button", {
538
- type: "button",
539
- "data-template-confirm": "",
540
- class: "flex-1 rounded bg-cn-accent/20 px-2 py-1 text-[12px] text-cn-accent hover:bg-cn-accent/30",
541
- onClick: (t) => N(e)
542
- }, " 创建 ", 8, Ce), h("button", {
543
- type: "button",
544
- class: "flex-1 rounded px-2 py-1 text-[12px] text-cn-muted hover:text-cn-fg",
545
- onClick: (t) => P(e)
546
- }, " 取消 ", 8, we)])
547
- ], 64)) : p("", !0)]),
629
+ }, " + ", 40, xe)]),
630
+ body: A(({ closeMenu: e }) => [f.value ? (w(), _(he, {
631
+ key: 0,
632
+ editor: r.editor,
633
+ onConfirm: (t) => S(t, e),
634
+ onCancel: (t) => ne(e)
635
+ }, null, 8, [
636
+ "editor",
637
+ "onConfirm",
638
+ "onCancel"
639
+ ])) : v("", !0)]),
548
640
  _: 1
549
- }, 8, ["items"]), S.value ? (b(), ie(i, {
550
- key: 0,
551
- ref_key: "pathPopupRef",
552
- ref: B,
553
- state: C(U),
554
- onSelect: C(Le)
555
- }, null, 8, ["state", "onSelect"])) : p("", !0)])]),
556
- Be.value ? p("", !0) : (b(), m("p", Te, " 画布还没有图层,用上方按钮新增 ")),
557
- h("ul", {
641
+ }, 8, ["items"])])]),
642
+ F.value ? v("", !0) : (w(), y("p", Se, " 画布还没有图层,用上方按钮新增 ")),
643
+ b("ul", {
558
644
  class: "cn-layers__tree flex flex-col gap-0.5 px-1.5 py-1",
559
- onDragend: Qe
560
- }, [(b(!0), m(d, null, se(W.value, (e) => (b(), m("li", {
645
+ onDragend: Pe
646
+ }, [(w(!0), y(h, null, re(P.value, (e) => (w(), y("li", {
561
647
  key: e.key,
562
648
  "data-key": e.key,
563
- draggable: Ye(e),
564
- class: v(["cn-layers__row group flex cursor-default select-none items-center gap-1 py-1 pr-1 text-[12px]", {
565
- "cn-layers__row--selected": Z(e),
566
- "cn-layers__row--hovered": $e(e) && !Z(e),
567
- "cn-layers__row--hidden": Y(e) && !e.node.visible,
649
+ draggable: pe(e),
650
+ class: C(["cn-layers__row group flex cursor-default select-none items-center gap-1 py-1 pr-1 text-[12px]", {
651
+ "cn-layers__row--selected": Fe(e),
652
+ "cn-layers__row--hovered": Ie(e) && !Fe(e),
653
+ "cn-layers__row--hidden": q(e) && !e.node.visible,
568
654
  "cn-layers__row--template": e.inTemplate,
569
- "cursor-grab": e.draggable && !Y(e),
570
- "cn-layers__row--drop-before": q.value?.key === e.key && q.value?.edge === "before",
571
- "cn-layers__row--drop-after": q.value?.key === e.key && q.value?.edge === "after"
655
+ "cursor-grab": e.draggable && !q(e),
656
+ "cn-layers__row--drop-before": G.value?.key === e.key && G.value?.edge === "before",
657
+ "cn-layers__row--drop-after": G.value?.key === e.key && G.value?.edge === "after"
572
658
  }]),
573
- style: oe({ paddingLeft: `${4 + e.indentLevel * 14}px` }),
574
- onClick: (t) => Ve(e),
575
- onMouseenter: (t) => G(e),
576
- onMouseleave: t[7] ||= (e) => G(null),
577
- onDragstart: (t) => Je(e, t),
578
- onDragover: (t) => Xe(e, t),
579
- onDrop: (t) => Ze(e, t)
659
+ style: te({ paddingLeft: `${4 + e.indentLevel * 14}px` }),
660
+ onClick: (t) => I(e),
661
+ onMouseenter: (t) => L(e),
662
+ onMouseleave: t[6] ||= (e) => L(null),
663
+ onDragstart: (t) => fe(e, t),
664
+ onDragover: (t) => me(e, t),
665
+ onDrop: (t) => X(e, t)
580
666
  }, [
581
- Y(e) ? (b(), m("span", {
667
+ q(e) ? (w(), y("span", {
582
668
  key: 0,
583
669
  "data-drag-handle": "",
584
670
  draggable: "true",
585
671
  title: "拖动排序",
586
672
  class: "cn-layers__handle shrink-0",
587
- onDragstart: (t) => X(e, t)
588
- }, [g(a, {
589
- icon: C(fe),
673
+ onDragstart: (t) => J(e, t)
674
+ }, [x(a, {
675
+ icon: O(ce),
590
676
  size: 12,
591
677
  "stroke-width": 2.5
592
- }, null, 8, ["icon"])], 40, De)) : p("", !0),
593
- e.node.expressionPrefix === "" ? p("", !0) : (b(), m("span", {
678
+ }, null, 8, ["icon"])], 40, we)) : v("", !0),
679
+ e.node.expressionPrefix === "" ? v("", !0) : (w(), y("span", {
594
680
  key: 1,
595
681
  class: "cn-layers__prefix",
596
682
  title: e.node.expressionPrefix
597
- }, ce(e.node.expressionPrefix), 9, Oe)),
598
- nt(e) ? E((b(), m("input", {
683
+ }, D(e.node.expressionPrefix), 9, Te)),
684
+ ze(e) ? j((w(), y("input", {
599
685
  key: 2,
600
686
  ref_for: !0,
601
- ref: tt,
602
- "onUpdate:modelValue": t[1] ||= (e) => Q.value = e,
687
+ ref: Re,
688
+ "onUpdate:modelValue": t[0] ||= (e) => Z.value = e,
603
689
  "data-rename-input": "",
604
690
  "aria-label": "图层重命名",
605
691
  class: "cn-layers__rename-input min-w-0 flex-1",
606
- onClick: t[2] ||= O(() => {}, ["stop"]),
607
- onDblclick: t[3] ||= O(() => {}, ["stop"]),
608
- onKeydown: [t[4] ||= D(O((e) => it(), ["prevent"]), ["enter"]), t[5] ||= D(O((e) => at(), ["prevent"]), ["esc"])],
609
- onBlur: t[6] ||= (e) => it()
610
- }, null, 544)), [[w, Q.value]]) : (b(), m("span", {
692
+ onClick: t[1] ||= M(() => {}, ["stop"]),
693
+ onDblclick: t[2] ||= M(() => {}, ["stop"]),
694
+ onKeydown: [t[3] ||= ae(M((e) => $(), ["prevent"]), ["enter"]), t[4] ||= ae(M((e) => Ve(), ["prevent"]), ["esc"])],
695
+ onBlur: t[5] ||= (e) => $()
696
+ }, null, 544)), [[k, Z.value]]) : (w(), y("span", {
611
697
  key: 3,
612
698
  class: "cn-layers__label min-w-0 flex-1 truncate font-mono text-[11px] leading-4",
613
- onDblclick: (t) => rt(e)
614
- }, ce(e.label), 41, ke)),
615
- Y(e) ? (b(), m("button", {
699
+ onDblclick: (t) => Be(e)
700
+ }, D(e.label), 41, Ee)),
701
+ q(e) ? (w(), y("button", {
616
702
  key: 4,
617
703
  type: "button",
618
704
  "data-visibility": "",
619
- class: v(["cn-layers__eye size-5 shrink-0 items-center justify-center rounded text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent", e.node.visible ? "hidden group-hover:flex" : "flex"]),
705
+ class: C(["cn-layers__eye size-5 shrink-0 items-center justify-center rounded text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent", e.node.visible ? "hidden group-hover:flex" : "flex"]),
620
706
  title: e.node.visible ? "隐藏图层(最终输出不含该层)" : "显示图层",
621
707
  "aria-pressed": !e.node.visible,
622
- onClick: O((t) => Ke(e), ["stop"])
623
- }, [g(a, {
624
- icon: e.node.visible ? C(de) : C(ue),
708
+ onClick: M((t) => H(e), ["stop"])
709
+ }, [x(a, {
710
+ icon: e.node.visible ? O(se) : O(oe),
625
711
  size: 11,
626
712
  "stroke-width": 2
627
- }, null, 8, ["icon"])], 10, Ae)) : p("", !0),
628
- Y(e) ? (b(), m("button", {
713
+ }, null, 8, ["icon"])], 10, De)) : v("", !0),
714
+ q(e) ? (w(), y("button", {
629
715
  key: 5,
630
716
  type: "button",
631
717
  "data-lock": "",
632
- class: v(["cn-layers__lock size-5 shrink-0 items-center justify-center rounded text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent", e.node.locked ? "flex" : "hidden group-hover:flex"]),
633
- title: e.node.locked ? o : "锁定图层(画布不可点选/拖动/删除,渲染照常)",
718
+ class: C(["cn-layers__lock size-5 shrink-0 items-center justify-center rounded text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent", e.node.locked ? "flex" : "hidden group-hover:flex"]),
719
+ title: e.node.locked ? i : "锁定图层(画布不可点选/拖动/删除,渲染照常)",
634
720
  "aria-pressed": e.node.locked,
635
- onClick: O((t) => qe(e), ["stop"])
636
- }, [g(a, {
637
- icon: e.node.locked ? C(me) : C(pe),
721
+ onClick: M((t) => U(e), ["stop"])
722
+ }, [x(a, {
723
+ icon: e.node.locked ? O(ue) : O(le),
638
724
  size: 11,
639
725
  "stroke-width": 2
640
- }, null, 8, ["icon"])], 10, je)) : p("", !0),
641
- Y(e) ? (b(), m("button", {
726
+ }, null, 8, ["icon"])], 10, Oe)) : v("", !0),
727
+ q(e) ? (w(), y("button", {
642
728
  key: 6,
643
729
  type: "button",
644
730
  "data-rename": "",
645
731
  class: "cn-layers__delete hidden size-5 shrink-0 items-center justify-center rounded text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent group-hover:flex",
646
732
  title: "重命名(双击名称或 F2)",
647
- onClick: O((t) => rt(e), ["stop"])
648
- }, [g(a, {
649
- icon: C(he),
733
+ onClick: M((t) => Be(e), ["stop"])
734
+ }, [x(a, {
735
+ icon: O(de),
650
736
  size: 11,
651
737
  "stroke-width": 2
652
- }, null, 8, ["icon"])], 8, Me)) : p("", !0),
653
- e.node.role === "root" && e.node.type === "TableLayer" ? (b(), m("button", {
738
+ }, null, 8, ["icon"])], 8, ke)) : v("", !0),
739
+ e.node.role === "root" && e.node.type === "TableLayer" ? (w(), y("button", {
654
740
  key: 7,
655
741
  type: "button",
656
742
  "data-add-row": "",
657
743
  class: "cn-layers__delete hidden size-5 shrink-0 items-center justify-center rounded text-[10px] leading-none text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent group-hover:flex disabled:cursor-not-allowed disabled:text-cn-muted/50 disabled:hover:bg-transparent",
658
744
  disabled: e.node.templated === !0,
659
745
  title: e.node.templated === !0 ? "模板态不可加行——行由数据展开" : "加行(缺省行 + 缺省格与文本,行宽=表宽)",
660
- onClick: O((t) => He(e), ["stop"])
661
- }, " +行 ", 8, Ne)) : p("", !0),
662
- e.node.role === "row" ? (b(), m("button", {
746
+ onClick: M((t) => R(e), ["stop"])
747
+ }, " +行 ", 8, Ae)) : v("", !0),
748
+ e.node.role === "row" ? (w(), y("button", {
663
749
  key: 8,
664
750
  type: "button",
665
751
  "data-add-cell": "",
666
752
  class: "cn-layers__delete hidden size-5 shrink-0 items-center justify-center rounded text-[10px] leading-none text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent group-hover:flex",
667
753
  title: "加格(缺省格 + 文本内容,行高取最高格)",
668
- onClick: O((t) => Ue(e), ["stop"])
669
- }, " +格 ", 8, Pe)) : p("", !0),
670
- e.node.role === "templateRow" ? (b(), m("button", {
754
+ onClick: M((t) => z(e), ["stop"])
755
+ }, " +格 ", 8, je)) : v("", !0),
756
+ e.node.role === "templateRow" ? (w(), y("button", {
671
757
  key: 9,
672
758
  type: "button",
673
759
  "data-add-template-cell": "",
674
760
  class: "cn-layers__delete hidden size-5 shrink-0 items-center justify-center rounded text-[10px] leading-none text-cn-muted hover:bg-cn-accent/15 hover:text-cn-accent group-hover:flex",
675
761
  title: "加格(缺省格 + 文本内容,零高度耦合——行高由数据展开定稿)",
676
- onClick: O((t) => We(e), ["stop"])
677
- }, " +格 ", 8, Fe)) : p("", !0),
678
- h("button", {
762
+ onClick: M((t) => B(e), ["stop"])
763
+ }, " +格 ", 8, Me)) : v("", !0),
764
+ b("button", {
679
765
  type: "button",
680
766
  class: "cn-layers__delete hidden size-5 shrink-0 items-center justify-center rounded text-[10px] leading-none text-cn-muted hover:bg-cn-danger/15 hover:text-cn-danger group-hover:flex disabled:cursor-not-allowed disabled:text-cn-muted/50 disabled:hover:bg-transparent disabled:hover:text-cn-muted/50",
681
767
  disabled: e.node.role === "templateRow" || e.node.locked,
682
- title: e.node.role === "templateRow" ? "行模板由表持有——转换回普通表请用 V2 转换入口" : e.node.locked ? _ : "删除(含子层)",
683
- onClick: O((t) => Ge(e), ["stop"])
684
- }, " ✕ ", 8, Ie)
685
- ], 46, Ee))), 128))], 32)
768
+ title: e.node.role === "templateRow" ? "行模板由表持有——转换回普通表请用 V2 转换入口" : e.node.locked ? o : "删除(含子层)",
769
+ onClick: M((t) => V(e), ["stop"])
770
+ }, " ✕ ", 8, Ne)
771
+ ], 46, Ce))), 128))], 32)
686
772
  ]));
687
773
  }
688
774
  });
689
775
  //#endregion
690
- export { I as a, B as i, H as n, R as o, V as r, z as s, U as t };
776
+ export { fe as a, U as c, he as i, Y as l, _e as n, V as o, ge as r, K as s, X as t };
@@ -1,2 +1,2 @@
1
- import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./layer-panel-DskyCgF5.js";
2
- export { t as ADD_LAYER_MENU, e as ADD_MENU, r as ADD_TEXT_PRESET_MENU, o as LayerPanel, a as PANEL_ADD_MENU, n as isUpperHalf, i as useLayerPanel };
1
+ import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c } from "./layer-panel-kOceTf8H.js";
2
+ export { e as ADD_LAYER_MENU, a as ADD_MENU, s as ADD_RATIO_PRESET_MENU, t as ADD_TEXT_PRESET_MENU, c as LayerPanel, r as PANEL_ADD_MENU, n as TemplateTableForm, i as isUpperHalf, o as useLayerPanel };
package/dist/style.css CHANGED
@@ -1,2 +1,2 @@
1
- .cn-align-float[data-v-9a761d37]{--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-field-line:#2a3a57;--cn-accent:#38bdf8;--cn-hover:#16223a;border:1px solid var(--cn-field-line);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--cn-fg);-webkit-user-select:none;user-select:none;background:#0b1220eb;border-radius:9px;align-items:center;gap:4px;padding:5px 8px;display:inline-flex;box-shadow:0 10px 26px #00000073}.cn-align-float__group[data-v-9a761d37]{align-items:center;gap:2px;display:flex}.cn-align-float__divider[data-v-9a761d37]{background:var(--cn-field-line);width:1px;height:16px}.cn-align-float__key[data-v-9a761d37]{width:24px;height:24px;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;place-content:center;padding:0;display:grid}.cn-align-float__key[data-v-9a761d37]:hover:not(:disabled){background:var(--cn-hover);color:var(--cn-accent)}.cn-align-float--disabled[data-v-9a761d37]{color:var(--cn-muted)}.cn-align-float--disabled .cn-align-float__key[data-v-9a761d37]{color:var(--cn-muted);cursor:not-allowed}.cn-context-menu[data-v-e554ef38]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-field:#94a3b812;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;--cn-danger:#f87171;z-index:30;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:10px;flex-direction:column;gap:2px;min-width:120px;padding:4px;display:flex;position:absolute;box-shadow:0 12px 32px #0206178c}.cn-context-menu__item[data-v-e554ef38]{color:var(--cn-fg);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;padding:6px 12px;font-size:13px;line-height:1.4}.cn-context-menu__item[data-v-e554ef38]:hover:not(:disabled){background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-context-menu__item[data-v-e554ef38]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-context-menu__item--delete[data-v-e554ef38]:hover:not(:disabled){color:var(--cn-danger);background:#f871711f}.cn-context-menu__form[data-v-e554ef38]{flex-direction:column;gap:6px;min-width:180px;padding:4px;display:flex}.cn-context-menu__hint[data-v-e554ef38]{color:var(--cn-muted);margin:0;padding:0 4px;font-size:11px;line-height:1.5}.cn-context-menu__hint--error[data-v-e554ef38]{color:var(--cn-danger)}.cn-context-menu__input[data-v-e554ef38]{border:1px solid var(--cn-line);background:var(--cn-field);color:var(--cn-fg);border-radius:6px;outline:none;padding:5px 8px;font-size:12px;line-height:1.4}.cn-context-menu__input[data-v-e554ef38]:focus{border-color:var(--cn-accent)}.cn-context-menu__input--invalid[data-v-e554ef38]{border-color:var(--cn-danger)}.cn-context-menu__form-actions[data-v-e554ef38]{gap:4px;display:flex}.cn-context-menu__form-actions .cn-context-menu__item[data-v-e554ef38]{text-align:center;flex:1}.cn-context-menu__item--confirm[data-v-e554ef38]{background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-find-bar[data-v-71f0a3ae]{--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-field-line:#2a3a57;--cn-accent:#38bdf8;--cn-hover:#16223a;z-index:25;border:1px solid var(--cn-field-line);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--cn-fg);-webkit-user-select:none;user-select:none;background:#0b1220eb;border-radius:9px;align-items:center;gap:6px;padding:6px 8px;display:inline-flex;position:absolute;top:12px;left:50%;transform:translate(-50%);box-shadow:0 10px 26px #00000073}.cn-find-bar__input[data-v-71f0a3ae]{border:1px solid var(--cn-field-line);width:132px;color:var(--cn-fg);background:#0b1220e6;border-radius:6px;padding:4px 8px;font-size:13px;line-height:1.4}.cn-find-bar__input[data-v-71f0a3ae]::placeholder{color:var(--cn-muted)}.cn-find-bar__input[data-v-71f0a3ae]:focus{border-color:var(--cn-accent);outline:none}.cn-find-bar__count[data-v-71f0a3ae]{text-align:center;min-width:56px;color:var(--cn-muted);white-space:nowrap;font-size:12px}.cn-find-bar__note[data-v-71f0a3ae]{color:var(--cn-accent);white-space:nowrap;font-size:12px}.cn-find-bar__key[data-v-71f0a3ae]{width:24px;height:24px;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;place-content:center;padding:0;display:grid}.cn-find-bar__action[data-v-71f0a3ae]{white-space:nowrap;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:4px 10px;font-size:12px;line-height:1.4}.cn-find-bar__key[data-v-71f0a3ae]:hover:not(:disabled),.cn-find-bar__action[data-v-71f0a3ae]:hover:not(:disabled){background:var(--cn-hover);color:var(--cn-accent)}.cn-find-bar__key[data-v-71f0a3ae]:disabled,.cn-find-bar__action[data-v-71f0a3ae]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-edit-toolbar[data-v-dcead501]{--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;z-index:30;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);pointer-events:auto;-webkit-user-select:none;user-select:none;border-radius:8px;align-items:stretch;gap:2px;padding:3px;display:inline-flex;position:absolute;top:0;left:0;box-shadow:0 8px 20px #02061773}.cn-edit-toolbar__segment+.cn-edit-toolbar__segment[data-v-dcead501]{border-left:1px solid var(--cn-line);margin-left:2px;padding-left:3px}.cn-edit-toolbar__segment[data-v-dcead501]{border-radius:5px;align-items:center;display:inline-flex;overflow:hidden}.cn-edit-toolbar__item[data-v-dcead501]{color:var(--cn-muted);white-space:nowrap;cursor:pointer;background:0 0;border:0;padding:3px 10px;font-size:11px;line-height:1.4}.cn-edit-toolbar__item+.cn-edit-toolbar__item[data-v-dcead501]{border-left:1px solid var(--cn-line)}.cn-edit-toolbar__item[data-v-dcead501]:hover{color:var(--cn-fg)}.cn-edit-toolbar__item--active[data-v-dcead501]{background:var(--cn-accent-soft);color:var(--cn-accent);cursor:default}.cn-edit-toolbar__icon-item[data-v-dcead501]{justify-content:center;align-items:center;padding:3px 6px;display:inline-flex}.cn-edit-toolbar__font[data-v-dcead501]{max-width:110px;height:22px;color:var(--cn-fg);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:0 2px;font-size:11px;line-height:1.4}.cn-edit-toolbar__font[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-edit-toolbar__font option[data-v-dcead501]{background:var(--cn-bg-elevated);color:var(--cn-fg)}.cn-edit-toolbar__mini[data-v-dcead501]{color:var(--cn-muted);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:3px 4px;display:inline-flex}.cn-edit-toolbar__mini[data-v-dcead501]:hover{color:var(--cn-fg)}.cn-edit-toolbar__size[data-v-dcead501]{border:1px solid var(--cn-line);width:34px;height:20px;color:var(--cn-fg);text-align:center;appearance:textfield;background:0 0;border-radius:4px;padding:0 2px;font-size:11px;line-height:1.4}.cn-edit-toolbar__size[data-v-dcead501]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.cn-edit-toolbar__size[data-v-dcead501]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.cn-edit-toolbar__size[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-edit-toolbar__color[data-v-dcead501]{border:1px solid var(--cn-line);cursor:pointer;background:0 0;border-radius:4px;width:24px;height:20px;padding:0}.cn-edit-toolbar__color[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-text-overlay[data-v-9e96d660]{pointer-events:none;position:absolute;inset:0}.cn-text-overlay__textarea[data-v-9e96d660]{resize:none;-webkit-user-select:text;user-select:text;pointer-events:auto;letter-spacing:normal;text-transform:none;background:0 0;border:0;outline:none;margin:0;padding:0;font-style:normal;font-weight:400;position:absolute;top:0;left:0;overflow:hidden}.cn-text-overlay__diagnostic[data-v-9e96d660]{text-overflow:ellipsis;white-space:nowrap;color:#f87171;pointer-events:none;-webkit-user-select:none;user-select:none;background:#0b1220e0;border:1px solid #f8717166;border-radius:4px;max-width:240px;padding:2px 6px;font-size:12px;line-height:16px;position:absolute;top:0;left:0;overflow:hidden}.cn-surface[data-v-f2b89db2]{touch-action:none;-webkit-user-select:none;user-select:none;position:relative;overflow:hidden}.cn-surface__canvas[data-v-f2b89db2]{width:100%;height:100%;display:block;position:absolute;inset:0}.cn-surface__canvas--overlay[data-v-f2b89db2]{pointer-events:none}.cn-surface--pannable[data-v-f2b89db2]{cursor:grab}.cn-surface--panning[data-v-f2b89db2]{cursor:grabbing}.cn-surface__drop-hint[data-v-f2b89db2]{z-index:20;pointer-events:none;background:#38bdf814;border:2px dashed #38bdf899;border-radius:12px;justify-content:center;align-items:center;display:flex;position:absolute;inset:8px}.cn-surface__drop-hint-text[data-v-f2b89db2]{color:#38bdf8;background:#0b1220;border-radius:8px;padding:6px 14px;font-size:13px;line-height:1.4}.cn-guides[data-v-61872121]{--cn-guide-line:#38bdf8;--cn-guide-glow:#38bdf866;--cn-guide-will-delete:#f87171;--cn-guide-will-delete-glow:#f8717173;--cn-snap-line:#fb7185;--cn-snap-glow:#fb718573;--cn-snap-dash:4px;--cn-guide-hit:9px;--cn-guide-clip-radius:12px;border-radius:var(--cn-guide-clip-radius);pointer-events:none;-webkit-user-select:none;user-select:none;position:absolute;inset:0;overflow:hidden}.cn-guides__guide[data-v-61872121]{pointer-events:auto;touch-action:none;position:absolute}.cn-guides__guide--vertical[data-v-61872121]{width:var(--cn-guide-hit);cursor:ew-resize;transform:translate(-50%)}.cn-guides__guide--horizontal[data-v-61872121]{height:var(--cn-guide-hit);cursor:ns-resize;transform:translateY(-50%)}.cn-guides__guide--vertical[data-v-61872121]:after,.cn-guides__guide--horizontal[data-v-61872121]:after{content:"";background:var(--cn-guide-line);box-shadow:0 0 6px var(--cn-guide-glow);position:absolute}.cn-guides__guide--vertical[data-v-61872121]:after{width:1px;top:0;bottom:0;left:calc(50% - .5px)}.cn-guides__guide--horizontal[data-v-61872121]:after{height:1px;top:calc(50% - .5px);left:0;right:0}.cn-guides__guide--preview[data-v-61872121]{pointer-events:none}.cn-guides__guide--preview[data-v-61872121]:after{opacity:.85}.cn-guides__guide--grabbed[data-v-61872121]:after{opacity:.75}.cn-guides__guide--will-delete[data-v-61872121]:after{background:var(--cn-guide-will-delete);box-shadow:0 0 6px var(--cn-guide-will-delete-glow)}.cn-guides__snap[data-v-61872121]{pointer-events:none;filter:drop-shadow(0 0 3px var(--cn-snap-glow));position:absolute}.cn-guides__snap--vertical[data-v-61872121]{background-image:repeating-linear-gradient(to bottom, var(--cn-snap-line) 0 var(--cn-snap-dash), transparent var(--cn-snap-dash) calc(var(--cn-snap-dash) * 2));width:1px}.cn-guides__snap--horizontal[data-v-61872121]{background-image:repeating-linear-gradient(to right, var(--cn-snap-line) 0 var(--cn-snap-dash), transparent var(--cn-snap-dash) calc(var(--cn-snap-dash) * 2));height:1px}.cn-ruler[data-v-5bd7248c]{--cn-ruler-thickness:20px;--cn-ruler-bg:#0b1220eb;--cn-ruler-line:#1e2a40;--cn-ruler-tick:#7c8ca5;--cn-ruler-label:#aab6c8;--cn-ruler-font:"SF Mono", Menlo, Consolas, monospace;pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;font-family:var(--cn-ruler-font);position:relative}.cn-ruler__bar[data-v-5bd7248c]{pointer-events:auto;touch-action:none;background:var(--cn-ruler-bg);position:absolute;top:0;left:0;overflow:hidden}.cn-ruler__bar--top[data-v-5bd7248c]{height:var(--cn-ruler-thickness);border-bottom:1px solid var(--cn-ruler-line);right:0}.cn-ruler__bar--left[data-v-5bd7248c]{width:var(--cn-ruler-thickness);border-right:1px solid var(--cn-ruler-line);bottom:0}.cn-ruler__corner[data-v-5bd7248c]{z-index:1;width:var(--cn-ruler-thickness);height:var(--cn-ruler-thickness);background:var(--cn-ruler-bg);border-right:1px solid var(--cn-ruler-line);border-bottom:1px solid var(--cn-ruler-line);position:absolute;top:0;left:0}.cn-ruler__tick[data-v-5bd7248c]{background:var(--cn-ruler-tick);position:absolute}.cn-ruler__bar--top .cn-ruler__tick[data-v-5bd7248c]{width:1px;height:4px;bottom:0}.cn-ruler__bar--top .cn-ruler__tick--major[data-v-5bd7248c]{height:8px}.cn-ruler__bar--left .cn-ruler__tick[data-v-5bd7248c]{width:4px;height:1px;right:0}.cn-ruler__bar--left .cn-ruler__tick--major[data-v-5bd7248c]{width:8px}.cn-ruler__label[data-v-5bd7248c]{white-space:nowrap;color:var(--cn-ruler-label);font-size:9px;line-height:1;position:absolute}.cn-ruler__bar--top .cn-ruler__label[data-v-5bd7248c]{bottom:9px;left:3px}.cn-ruler__bar--left .cn-ruler__label[data-v-5bd7248c]{writing-mode:vertical-rl;top:2px;right:10px}.cn-dropdown[data-v-ec8a19c1]{--cn-fg:#e6edf7;--cn-fg-2:#c3cddd;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-bg-elevated:#101a2e;--cn-hover:#16223a;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;display:inline-flex;position:relative}.cn-dropdown__trigger[data-v-ec8a19c1]{white-space:nowrap;color:var(--cn-fg-2);cursor:pointer;background:0 0;border:none;border-radius:6px;align-items:center;gap:3px;padding:5px 9px;font-size:13px;display:inline-flex}.cn-dropdown__trigger[data-v-ec8a19c1]:hover{background:var(--cn-hover);color:var(--cn-fg)}.cn-dropdown__caret[data-v-ec8a19c1]{color:var(--cn-muted);font-size:10px;line-height:1}.cn-dropdown__menu[data-v-ec8a19c1]{z-index:40;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:10px;flex-direction:column;gap:2px;min-width:148px;padding:4px;display:flex;position:fixed;box-shadow:0 12px 32px #0206178c}.cn-dropdown__item[data-v-ec8a19c1]{color:var(--cn-fg);text-align:left;white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:space-between;align-items:center;gap:14px;padding:6px 12px;font-size:12px;line-height:1.4;display:flex}.cn-dropdown__item[data-v-ec8a19c1]:hover:not(:disabled){background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-dropdown__item[data-v-ec8a19c1]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-dropdown__shortcut[data-v-ec8a19c1]{color:var(--cn-muted);font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:1.4}.cn-dropdown__separator[data-v-ec8a19c1]{background:var(--cn-line);flex:none;height:1px;margin:3px 6px}.cn-statusbar[data-v-040479fb]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;background-color:var(--cn-bg);color:var(--cn-muted);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;align-items:center;gap:10px;padding:6px 12px;font-size:12px;line-height:1.4;display:flex}.cn-statusbar__segment[data-v-040479fb]{white-space:nowrap}.cn-statusbar__zoom-trigger[data-v-040479fb]{font:inherit;color:inherit;font-variant-numeric:tabular-nums;cursor:pointer;background:0 0;border:0;padding:0}.cn-statusbar__zoom-trigger[data-v-040479fb]:hover{color:var(--cn-accent)}.cn-statusbar__help[data-v-040479fb]{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0;padding:0}.cn-statusbar__help[data-v-040479fb]:hover,.cn-statusbar__segment--pending[data-v-040479fb]{color:var(--cn-accent)}.cn-statusbar__divider[data-v-040479fb]{background:var(--cn-line);width:1px;height:12px}.cn-help[data-v-486e5be3]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;z-index:50;background:#0206178c;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.cn-help__panel[data-v-486e5be3]{background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:12px;flex-direction:column;min-width:320px;max-width:480px;max-height:100%;display:flex;box-shadow:0 24px 64px #02061799}.cn-help__header[data-v-486e5be3]{border-bottom:1px solid var(--cn-line);justify-content:space-between;align-items:center;padding:12px 16px;display:flex}.cn-help__title[data-v-486e5be3]{color:var(--cn-fg);margin:0;font-size:14px;font-weight:600;line-height:1.4}.cn-help__close[data-v-486e5be3]{color:var(--cn-muted);cursor:pointer;background:0 0;border:0;border-radius:6px;padding:2px 8px;font-size:13px;line-height:1.4}.cn-help__close[data-v-486e5be3]:hover{color:var(--cn-fg);background:#94a3b812}.cn-help__body[data-v-486e5be3]{padding:8px 16px 16px;overflow-y:auto}.cn-help__section[data-v-486e5be3]{margin-top:12px}.cn-help__section[data-v-486e5be3]:first-child{margin-top:8px}.cn-help__section-title[data-v-486e5be3]{color:var(--cn-accent);margin:0 0 4px;font-size:11px;font-weight:600;line-height:1.4}.cn-help__list[data-v-486e5be3]{margin:0;padding:0;list-style:none}.cn-help__row[data-v-486e5be3]{justify-content:space-between;align-items:baseline;gap:16px;padding:3px 0;display:flex}.cn-help__label[data-v-486e5be3]{color:var(--cn-fg);font-size:12px;line-height:1.5}.cn-help__keys[data-v-486e5be3]{border:1px solid var(--cn-line);color:var(--cn-muted);white-space:nowrap;background:#94a3b812;border-radius:5px;flex-shrink:0;padding:1px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.4}
1
+ .cn-align-float[data-v-9a761d37]{--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-field-line:#2a3a57;--cn-accent:#38bdf8;--cn-hover:#16223a;border:1px solid var(--cn-field-line);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--cn-fg);-webkit-user-select:none;user-select:none;background:#0b1220eb;border-radius:9px;align-items:center;gap:4px;padding:5px 8px;display:inline-flex;box-shadow:0 10px 26px #00000073}.cn-align-float__group[data-v-9a761d37]{align-items:center;gap:2px;display:flex}.cn-align-float__divider[data-v-9a761d37]{background:var(--cn-field-line);width:1px;height:16px}.cn-align-float__key[data-v-9a761d37]{width:24px;height:24px;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;place-content:center;padding:0;display:grid}.cn-align-float__key[data-v-9a761d37]:hover:not(:disabled){background:var(--cn-hover);color:var(--cn-accent)}.cn-align-float--disabled[data-v-9a761d37]{color:var(--cn-muted)}.cn-align-float--disabled .cn-align-float__key[data-v-9a761d37]{color:var(--cn-muted);cursor:not-allowed}.cn-context-menu[data-v-e554ef38]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-field:#94a3b812;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;--cn-danger:#f87171;z-index:30;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:10px;flex-direction:column;gap:2px;min-width:120px;padding:4px;display:flex;position:absolute;box-shadow:0 12px 32px #0206178c}.cn-context-menu__item[data-v-e554ef38]{color:var(--cn-fg);text-align:left;cursor:pointer;background:0 0;border:0;border-radius:6px;padding:6px 12px;font-size:13px;line-height:1.4}.cn-context-menu__item[data-v-e554ef38]:hover:not(:disabled){background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-context-menu__item[data-v-e554ef38]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-context-menu__item--delete[data-v-e554ef38]:hover:not(:disabled){color:var(--cn-danger);background:#f871711f}.cn-context-menu__form[data-v-e554ef38]{flex-direction:column;gap:6px;min-width:180px;padding:4px;display:flex}.cn-context-menu__hint[data-v-e554ef38]{color:var(--cn-muted);margin:0;padding:0 4px;font-size:11px;line-height:1.5}.cn-context-menu__hint--error[data-v-e554ef38]{color:var(--cn-danger)}.cn-context-menu__input[data-v-e554ef38]{border:1px solid var(--cn-line);background:var(--cn-field);color:var(--cn-fg);border-radius:6px;outline:none;padding:5px 8px;font-size:12px;line-height:1.4}.cn-context-menu__input[data-v-e554ef38]:focus{border-color:var(--cn-accent)}.cn-context-menu__input--invalid[data-v-e554ef38]{border-color:var(--cn-danger)}.cn-context-menu__form-actions[data-v-e554ef38]{gap:4px;display:flex}.cn-context-menu__form-actions .cn-context-menu__item[data-v-e554ef38]{text-align:center;flex:1}.cn-context-menu__item--confirm[data-v-e554ef38]{background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-find-bar[data-v-71f0a3ae]{--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-field-line:#2a3a57;--cn-accent:#38bdf8;--cn-hover:#16223a;z-index:25;border:1px solid var(--cn-field-line);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--cn-fg);-webkit-user-select:none;user-select:none;background:#0b1220eb;border-radius:9px;align-items:center;gap:6px;padding:6px 8px;display:inline-flex;position:absolute;top:12px;left:50%;transform:translate(-50%);box-shadow:0 10px 26px #00000073}.cn-find-bar__input[data-v-71f0a3ae]{border:1px solid var(--cn-field-line);width:132px;color:var(--cn-fg);background:#0b1220e6;border-radius:6px;padding:4px 8px;font-size:13px;line-height:1.4}.cn-find-bar__input[data-v-71f0a3ae]::placeholder{color:var(--cn-muted)}.cn-find-bar__input[data-v-71f0a3ae]:focus{border-color:var(--cn-accent);outline:none}.cn-find-bar__count[data-v-71f0a3ae]{text-align:center;min-width:56px;color:var(--cn-muted);white-space:nowrap;font-size:12px}.cn-find-bar__note[data-v-71f0a3ae]{color:var(--cn-accent);white-space:nowrap;font-size:12px}.cn-find-bar__key[data-v-71f0a3ae]{width:24px;height:24px;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;place-content:center;padding:0;display:grid}.cn-find-bar__action[data-v-71f0a3ae]{white-space:nowrap;color:var(--cn-fg);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:4px 10px;font-size:12px;line-height:1.4}.cn-find-bar__key[data-v-71f0a3ae]:hover:not(:disabled),.cn-find-bar__action[data-v-71f0a3ae]:hover:not(:disabled){background:var(--cn-hover);color:var(--cn-accent)}.cn-find-bar__key[data-v-71f0a3ae]:disabled,.cn-find-bar__action[data-v-71f0a3ae]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-edit-toolbar[data-v-dcead501]{--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;z-index:30;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);pointer-events:auto;-webkit-user-select:none;user-select:none;border-radius:8px;align-items:stretch;gap:2px;padding:3px;display:inline-flex;position:absolute;top:0;left:0;box-shadow:0 8px 20px #02061773}.cn-edit-toolbar__segment+.cn-edit-toolbar__segment[data-v-dcead501]{border-left:1px solid var(--cn-line);margin-left:2px;padding-left:3px}.cn-edit-toolbar__segment[data-v-dcead501]{border-radius:5px;align-items:center;display:inline-flex;overflow:hidden}.cn-edit-toolbar__item[data-v-dcead501]{color:var(--cn-muted);white-space:nowrap;cursor:pointer;background:0 0;border:0;padding:3px 10px;font-size:11px;line-height:1.4}.cn-edit-toolbar__item+.cn-edit-toolbar__item[data-v-dcead501]{border-left:1px solid var(--cn-line)}.cn-edit-toolbar__item[data-v-dcead501]:hover{color:var(--cn-fg)}.cn-edit-toolbar__item--active[data-v-dcead501]{background:var(--cn-accent-soft);color:var(--cn-accent);cursor:default}.cn-edit-toolbar__icon-item[data-v-dcead501]{justify-content:center;align-items:center;padding:3px 6px;display:inline-flex}.cn-edit-toolbar__font[data-v-dcead501]{max-width:110px;height:22px;color:var(--cn-fg);cursor:pointer;background:0 0;border:0;border-radius:4px;padding:0 2px;font-size:11px;line-height:1.4}.cn-edit-toolbar__font[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-edit-toolbar__font option[data-v-dcead501]{background:var(--cn-bg-elevated);color:var(--cn-fg)}.cn-edit-toolbar__mini[data-v-dcead501]{color:var(--cn-muted);cursor:pointer;background:0 0;border:0;justify-content:center;align-items:center;padding:3px 4px;display:inline-flex}.cn-edit-toolbar__mini[data-v-dcead501]:hover{color:var(--cn-fg)}.cn-edit-toolbar__size[data-v-dcead501]{border:1px solid var(--cn-line);width:34px;height:20px;color:var(--cn-fg);text-align:center;appearance:textfield;background:0 0;border-radius:4px;padding:0 2px;font-size:11px;line-height:1.4}.cn-edit-toolbar__size[data-v-dcead501]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.cn-edit-toolbar__size[data-v-dcead501]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.cn-edit-toolbar__size[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-edit-toolbar__color[data-v-dcead501]{border:1px solid var(--cn-line);cursor:pointer;background:0 0;border-radius:4px;width:24px;height:20px;padding:0}.cn-edit-toolbar__color[data-v-dcead501]:focus-visible{outline:1px solid var(--cn-accent)}.cn-text-overlay[data-v-9e96d660]{pointer-events:none;position:absolute;inset:0}.cn-text-overlay__textarea[data-v-9e96d660]{resize:none;-webkit-user-select:text;user-select:text;pointer-events:auto;letter-spacing:normal;text-transform:none;background:0 0;border:0;outline:none;margin:0;padding:0;font-style:normal;font-weight:400;position:absolute;top:0;left:0;overflow:hidden}.cn-text-overlay__diagnostic[data-v-9e96d660]{text-overflow:ellipsis;white-space:nowrap;color:#f87171;pointer-events:none;-webkit-user-select:none;user-select:none;background:#0b1220e0;border:1px solid #f8717166;border-radius:4px;max-width:240px;padding:2px 6px;font-size:12px;line-height:16px;position:absolute;top:0;left:0;overflow:hidden}.cn-surface[data-v-2327ee46]{touch-action:none;-webkit-user-select:none;user-select:none;position:relative;overflow:hidden}.cn-surface__canvas[data-v-2327ee46]{width:100%;height:100%;display:block;position:absolute;inset:0}.cn-surface__canvas--overlay[data-v-2327ee46]{pointer-events:none}.cn-surface--pannable[data-v-2327ee46]{cursor:grab}.cn-surface--panning[data-v-2327ee46]{cursor:grabbing}.cn-surface__drop-hint[data-v-2327ee46]{z-index:20;pointer-events:none;background:#38bdf814;border:2px dashed #38bdf899;border-radius:12px;justify-content:center;align-items:center;display:flex;position:absolute;inset:8px}.cn-surface__drop-hint-text[data-v-2327ee46]{color:#38bdf8;background:#0b1220;border-radius:8px;padding:6px 14px;font-size:13px;line-height:1.4}.cn-guides[data-v-61872121]{--cn-guide-line:#38bdf8;--cn-guide-glow:#38bdf866;--cn-guide-will-delete:#f87171;--cn-guide-will-delete-glow:#f8717173;--cn-snap-line:#fb7185;--cn-snap-glow:#fb718573;--cn-snap-dash:4px;--cn-guide-hit:9px;--cn-guide-clip-radius:12px;border-radius:var(--cn-guide-clip-radius);pointer-events:none;-webkit-user-select:none;user-select:none;position:absolute;inset:0;overflow:hidden}.cn-guides__guide[data-v-61872121]{pointer-events:auto;touch-action:none;position:absolute}.cn-guides__guide--vertical[data-v-61872121]{width:var(--cn-guide-hit);cursor:ew-resize;transform:translate(-50%)}.cn-guides__guide--horizontal[data-v-61872121]{height:var(--cn-guide-hit);cursor:ns-resize;transform:translateY(-50%)}.cn-guides__guide--vertical[data-v-61872121]:after,.cn-guides__guide--horizontal[data-v-61872121]:after{content:"";background:var(--cn-guide-line);box-shadow:0 0 6px var(--cn-guide-glow);position:absolute}.cn-guides__guide--vertical[data-v-61872121]:after{width:1px;top:0;bottom:0;left:calc(50% - .5px)}.cn-guides__guide--horizontal[data-v-61872121]:after{height:1px;top:calc(50% - .5px);left:0;right:0}.cn-guides__guide--preview[data-v-61872121]{pointer-events:none}.cn-guides__guide--preview[data-v-61872121]:after{opacity:.85}.cn-guides__guide--grabbed[data-v-61872121]:after{opacity:.75}.cn-guides__guide--will-delete[data-v-61872121]:after{background:var(--cn-guide-will-delete);box-shadow:0 0 6px var(--cn-guide-will-delete-glow)}.cn-guides__snap[data-v-61872121]{pointer-events:none;filter:drop-shadow(0 0 3px var(--cn-snap-glow));position:absolute}.cn-guides__snap--vertical[data-v-61872121]{background-image:repeating-linear-gradient(to bottom, var(--cn-snap-line) 0 var(--cn-snap-dash), transparent var(--cn-snap-dash) calc(var(--cn-snap-dash) * 2));width:1px}.cn-guides__snap--horizontal[data-v-61872121]{background-image:repeating-linear-gradient(to right, var(--cn-snap-line) 0 var(--cn-snap-dash), transparent var(--cn-snap-dash) calc(var(--cn-snap-dash) * 2));height:1px}.cn-ruler[data-v-5bd7248c]{--cn-ruler-thickness:20px;--cn-ruler-bg:#0b1220eb;--cn-ruler-line:#1e2a40;--cn-ruler-tick:#7c8ca5;--cn-ruler-label:#aab6c8;--cn-ruler-font:"SF Mono", Menlo, Consolas, monospace;pointer-events:none;-webkit-user-select:none;user-select:none;width:100%;height:100%;font-family:var(--cn-ruler-font);position:relative}.cn-ruler__bar[data-v-5bd7248c]{pointer-events:auto;touch-action:none;background:var(--cn-ruler-bg);position:absolute;top:0;left:0;overflow:hidden}.cn-ruler__bar--top[data-v-5bd7248c]{height:var(--cn-ruler-thickness);border-bottom:1px solid var(--cn-ruler-line);right:0}.cn-ruler__bar--left[data-v-5bd7248c]{width:var(--cn-ruler-thickness);border-right:1px solid var(--cn-ruler-line);bottom:0}.cn-ruler__corner[data-v-5bd7248c]{z-index:1;width:var(--cn-ruler-thickness);height:var(--cn-ruler-thickness);background:var(--cn-ruler-bg);border-right:1px solid var(--cn-ruler-line);border-bottom:1px solid var(--cn-ruler-line);position:absolute;top:0;left:0}.cn-ruler__tick[data-v-5bd7248c]{background:var(--cn-ruler-tick);position:absolute}.cn-ruler__bar--top .cn-ruler__tick[data-v-5bd7248c]{width:1px;height:4px;bottom:0}.cn-ruler__bar--top .cn-ruler__tick--major[data-v-5bd7248c]{height:8px}.cn-ruler__bar--left .cn-ruler__tick[data-v-5bd7248c]{width:4px;height:1px;right:0}.cn-ruler__bar--left .cn-ruler__tick--major[data-v-5bd7248c]{width:8px}.cn-ruler__label[data-v-5bd7248c]{white-space:nowrap;color:var(--cn-ruler-label);font-size:9px;line-height:1;position:absolute}.cn-ruler__bar--top .cn-ruler__label[data-v-5bd7248c]{bottom:9px;left:3px}.cn-ruler__bar--left .cn-ruler__label[data-v-5bd7248c]{writing-mode:vertical-rl;top:2px;right:10px}.cn-dropdown[data-v-ec8a19c1]{--cn-fg:#e6edf7;--cn-fg-2:#c3cddd;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-bg-elevated:#101a2e;--cn-hover:#16223a;--cn-accent:#38bdf8;--cn-accent-soft:#38bdf81f;display:inline-flex;position:relative}.cn-dropdown__trigger[data-v-ec8a19c1]{white-space:nowrap;color:var(--cn-fg-2);cursor:pointer;background:0 0;border:none;border-radius:6px;align-items:center;gap:3px;padding:5px 9px;font-size:13px;display:inline-flex}.cn-dropdown__trigger[data-v-ec8a19c1]:hover{background:var(--cn-hover);color:var(--cn-fg)}.cn-dropdown__caret[data-v-ec8a19c1]{color:var(--cn-muted);font-size:10px;line-height:1}.cn-dropdown__menu[data-v-ec8a19c1]{z-index:40;background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:10px;flex-direction:column;gap:2px;min-width:148px;padding:4px;display:flex;position:fixed;box-shadow:0 12px 32px #0206178c}.cn-dropdown__item[data-v-ec8a19c1]{color:var(--cn-fg);text-align:left;white-space:nowrap;cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:space-between;align-items:center;gap:14px;padding:6px 12px;font-size:12px;line-height:1.4;display:flex}.cn-dropdown__item[data-v-ec8a19c1]:hover:not(:disabled){background:var(--cn-accent-soft);color:var(--cn-accent)}.cn-dropdown__item[data-v-ec8a19c1]:disabled{color:var(--cn-muted);cursor:not-allowed}.cn-dropdown__shortcut[data-v-ec8a19c1]{color:var(--cn-muted);font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:1.4}.cn-dropdown__separator[data-v-ec8a19c1]{background:var(--cn-line);flex:none;height:1px;margin:3px 6px}.cn-statusbar[data-v-040479fb]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;background-color:var(--cn-bg);color:var(--cn-muted);font-variant-numeric:tabular-nums;-webkit-user-select:none;user-select:none;align-items:center;gap:10px;padding:6px 12px;font-size:12px;line-height:1.4;display:flex}.cn-statusbar__segment[data-v-040479fb]{white-space:nowrap}.cn-statusbar__zoom-trigger[data-v-040479fb]{font:inherit;color:inherit;font-variant-numeric:tabular-nums;cursor:pointer;background:0 0;border:0;padding:0}.cn-statusbar__zoom-trigger[data-v-040479fb]:hover{color:var(--cn-accent)}.cn-statusbar__help[data-v-040479fb]{font:inherit;color:inherit;cursor:pointer;background:0 0;border:0;padding:0}.cn-statusbar__help[data-v-040479fb]:hover,.cn-statusbar__segment--pending[data-v-040479fb]{color:var(--cn-accent)}.cn-statusbar__divider[data-v-040479fb]{background:var(--cn-line);width:1px;height:12px}.cn-help[data-v-486e5be3]{--cn-bg:#0b1220;--cn-bg-elevated:#101a2e;--cn-fg:#e6edf7;--cn-muted:#7c8ca5;--cn-line:#1e2a40;--cn-accent:#38bdf8;z-index:50;background:#0206178c;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.cn-help__panel[data-v-486e5be3]{background:var(--cn-bg-elevated);border:1px solid var(--cn-line);border-radius:12px;flex-direction:column;min-width:320px;max-width:480px;max-height:100%;display:flex;box-shadow:0 24px 64px #02061799}.cn-help__header[data-v-486e5be3]{border-bottom:1px solid var(--cn-line);justify-content:space-between;align-items:center;padding:12px 16px;display:flex}.cn-help__title[data-v-486e5be3]{color:var(--cn-fg);margin:0;font-size:14px;font-weight:600;line-height:1.4}.cn-help__close[data-v-486e5be3]{color:var(--cn-muted);cursor:pointer;background:0 0;border:0;border-radius:6px;padding:2px 8px;font-size:13px;line-height:1.4}.cn-help__close[data-v-486e5be3]:hover{color:var(--cn-fg);background:#94a3b812}.cn-help__body[data-v-486e5be3]{padding:8px 16px 16px;overflow-y:auto}.cn-help__section[data-v-486e5be3]{margin-top:12px}.cn-help__section[data-v-486e5be3]:first-child{margin-top:8px}.cn-help__section-title[data-v-486e5be3]{color:var(--cn-accent);margin:0 0 4px;font-size:11px;font-weight:600;line-height:1.4}.cn-help__list[data-v-486e5be3]{margin:0;padding:0;list-style:none}.cn-help__row[data-v-486e5be3]{justify-content:space-between;align-items:baseline;gap:16px;padding:3px 0;display:flex}.cn-help__label[data-v-486e5be3]{color:var(--cn-fg);font-size:12px;line-height:1.5}.cn-help__keys[data-v-486e5be3]{border:1px solid var(--cn-line);color:var(--cn-muted);white-space:nowrap;background:#94a3b812;border-radius:5px;flex-shrink:0;padding:1px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.4}
2
2
  /*$vite$:1*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hankchen/canvas-editor-vue",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "license": "MIT",
5
5
  "description": "Vue 3 薄绑定:响应式桥、composables、画布表面组件、textarea 文本编辑 overlay、schema 驱动属性面板注册表",
6
6
  "type": "module",
@@ -58,7 +58,7 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@lucide/vue": "^1.48.0",
61
- "@hankchen/canvas-editor": "0.5.0"
61
+ "@hankchen/canvas-editor": "0.6.0"
62
62
  },
63
63
  "peerDependencies": {
64
64
  "vue": "^3.5.0"