vkedit 3.2.7 → 4.0.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 (95) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.en.md +38 -36
  3. package/README.md +32 -28
  4. package/dist/commands/change-layer-order-command.d.ts +1 -0
  5. package/dist/commands/index.d.ts +1 -0
  6. package/dist/commands/reorder-elements-command.d.ts +19 -0
  7. package/dist/components/BaseElementPropertyPanel.vue.d.ts +28 -1
  8. package/dist/components/TextProperty.vue.d.ts +2 -0
  9. package/dist/components/ui/VkButton.vue.d.ts +2 -2
  10. package/dist/components/ui/VkColorPicker.vue.d.ts +26 -0
  11. package/dist/components/ui/VkTextarea.vue.d.ts +20 -0
  12. package/dist/components/ui/index.d.ts +2 -1
  13. package/dist/core/ContentLayer.vue.d.ts +0 -2
  14. package/dist/core/Editor.vue.d.ts +1 -0
  15. package/dist/{plugins/rect/Tool.vue.d.ts → core/GraphicToolRenderer.vue.d.ts} +6 -1
  16. package/dist/core/HelpGuide.vue.d.ts +3 -1
  17. package/dist/{plugins/table/CellsBorder.vue.d.ts → core/TransformOverlay.vue.d.ts} +2 -2
  18. package/dist/core/editor-host.d.ts +2 -11
  19. package/dist/favicon.ico +0 -0
  20. package/dist/favicon.svg +8 -0
  21. package/dist/hooks/index.d.ts +1 -0
  22. package/dist/hooks/use-content-layer.d.ts +6 -6
  23. package/dist/hooks/use-host-state.d.ts +1 -0
  24. package/dist/hooks/use-ruler-layer.d.ts +24 -0
  25. package/dist/hooks/use-selection-layer.d.ts +2 -3
  26. package/dist/hooks/use-stage-event.d.ts +1 -0
  27. package/dist/hooks/use-transform-overlay.d.ts +108 -0
  28. package/dist/index-CSKpw1uX.js +25597 -0
  29. package/dist/{index.es-B1gCGYT7.js → index.es-Dswe047Z.js} +1 -1
  30. package/dist/plugins/barcode/Shape.vue.d.ts +1 -1
  31. package/dist/plugins/barcode/barcode.d.ts +12 -13
  32. package/dist/plugins/barcode/index.d.ts +0 -1
  33. package/dist/plugins/export/export.d.ts +1 -2
  34. package/dist/plugins/graphic-registry/graphic-registry.d.ts +43 -0
  35. package/dist/plugins/graphic-registry/index.d.ts +1 -0
  36. package/dist/plugins/import/import.d.ts +1 -2
  37. package/dist/plugins/index.d.ts +2 -6
  38. package/dist/plugins/{table/ContextMenu.vue.d.ts → layer-manager/LayerPanel.vue.d.ts} +5 -4
  39. package/dist/plugins/layer-manager/index.d.ts +2 -0
  40. package/dist/plugins/layer-manager/layer-manager.d.ts +16 -0
  41. package/dist/plugins/line/Shape.vue.d.ts +1 -1
  42. package/dist/plugins/line/index.d.ts +0 -1
  43. package/dist/plugins/line/line.d.ts +12 -13
  44. package/dist/plugins/qrcode/Shape.vue.d.ts +1 -1
  45. package/dist/plugins/qrcode/index.d.ts +0 -1
  46. package/dist/plugins/qrcode/qrcode.d.ts +12 -13
  47. package/dist/plugins/rect/Shape.vue.d.ts +1 -1
  48. package/dist/plugins/rect/index.d.ts +0 -1
  49. package/dist/plugins/rect/rect.d.ts +11 -13
  50. package/dist/plugins/selection.d.ts +0 -1
  51. package/dist/plugins/text/Shape.vue.d.ts +1 -1
  52. package/dist/plugins/text/index.d.ts +0 -1
  53. package/dist/plugins/text/text.d.ts +16 -13
  54. package/dist/types/base-graphic-element.d.ts +10 -3
  55. package/dist/types/base.d.ts +5 -18
  56. package/dist/types/event-data.d.ts +17 -0
  57. package/dist/types/event-map.d.ts +8 -1
  58. package/dist/types/graphic-plugin.d.ts +27 -0
  59. package/dist/types/index.d.ts +1 -3
  60. package/dist/utils/color.d.ts +40 -0
  61. package/dist/utils/css-var.d.ts +14 -0
  62. package/dist/utils/index.d.ts +4 -0
  63. package/dist/utils/readability.d.ts +22 -0
  64. package/dist/utils/theme.d.ts +2 -0
  65. package/dist/utils/transform-geometry.d.ts +62 -0
  66. package/dist/utils/transform-overlay.d.ts +62 -0
  67. package/dist/vkedit.css +1 -1
  68. package/dist/vkedit.es.js +81 -96
  69. package/package.json +4 -5
  70. package/dist/components/ui/VkIcon.vue.d.ts +0 -8
  71. package/dist/index-Aa1HXlw6.js +0 -72887
  72. package/dist/plugins/barcode/Tool.vue.d.ts +0 -6
  73. package/dist/plugins/chart/PropertyPanel.vue.d.ts +0 -9
  74. package/dist/plugins/chart/Shape.vue.d.ts +0 -23
  75. package/dist/plugins/chart/Tool.vue.d.ts +0 -6
  76. package/dist/plugins/chart/chart.d.ts +0 -38
  77. package/dist/plugins/chart/index.d.ts +0 -4
  78. package/dist/plugins/element-manager.d.ts +0 -24
  79. package/dist/plugins/graphic-manager/graphic-manager.d.ts +0 -31
  80. package/dist/plugins/graphic-manager/index.d.ts +0 -1
  81. package/dist/plugins/graphic-tool-manager.d.ts +0 -16
  82. package/dist/plugins/line/Tool.vue.d.ts +0 -7
  83. package/dist/plugins/property-panel-manager/index.d.ts +0 -1
  84. package/dist/plugins/property-panel-manager/property-panel-manager.d.ts +0 -32
  85. package/dist/plugins/qrcode/Tool.vue.d.ts +0 -6
  86. package/dist/plugins/table/PropertyPanel.vue.d.ts +0 -9
  87. package/dist/plugins/table/Shape.vue.d.ts +0 -26
  88. package/dist/plugins/table/Tool.vue.d.ts +0 -7
  89. package/dist/plugins/table/cell.d.ts +0 -61
  90. package/dist/plugins/table/index.d.ts +0 -6
  91. package/dist/plugins/table/table.d.ts +0 -92
  92. package/dist/plugins/text/Tool.vue.d.ts +0 -6
  93. package/dist/types/base-graphic-type.d.ts +0 -9
  94. package/dist/types/element-type-map.d.ts +0 -12
  95. package/dist/types/plugin-map.d.ts +0 -12
package/CHANGELOG.md ADDED
@@ -0,0 +1,51 @@
1
+ # Changelog
2
+
3
+ ## [4.0.0] - 2026-07-21
4
+
5
+ ### BREAKING CHANGE (styles)
6
+
7
+ - **Design Token 重命名/删除** — 废弃 `--vkedit-color-white`、`--vkedit-color-gray-*`、`--vkedit-color-bg-dark*`、`--vkedit-color-border-dark*`、`--vkedit-color-text-dark*` 等旧变量,改用统一语义 Token(详见 [MIGRATION.md](./MIGRATION.md))
8
+ - **默认暗色主题** — 编辑器根节点默认 `data-vkedit-theme="dark"`,废除原 `body:has(.vkedit-editor)` 深色覆盖方案
9
+ - **Primary 色变更为 teal** — 品牌色从蓝色系切换为 teal 系,若需还原请覆盖 `--vkedit-color-primary` 等 CSS 变量
10
+ - **移除 `--vkedit-color-neutral-*` 零散阶梯** — 统一为 `--vkedit-palette-neutral-*`(0~950 完整阶梯)
11
+
12
+ ### Features
13
+
14
+ - **teal primary 品牌色** — 暗色 `--vkedit-palette-teal-500`、亮色 `--vkedit-palette-teal-600`,统一 Vk* 组件与壳层视觉
15
+ - **Design Token 体系** — 两层架构:Palette(`:root`)+ Semantic(主题选择器),组件只引用语义变量
16
+ - **VkButton `variant="primary"`** — 新增 primary/destructive/outline/secondary/ghost/link 变体
17
+ - **Teleport 浮层主题继承** — 弹出层自动携带 `data-vkedit-theme`,浮层在 DOM 外也能正确渲染主题色
18
+ - **主题解析工具** — `resolveVkeditTheme(el)` 工具函数,供自定义组件获取当前主题
19
+ - **完整 CSS 变量集** — 包含 spacing、radius、font、shadow、elevation、z-index、control-height 等基础设施
20
+
21
+ ### Added
22
+
23
+ - **`GraphicPlugin<T>` 抽象基类** — 新增统一插件基类,子类只需声明 `graphicType`、`graphicElement`、`shapeComponent`、`toolComponent`、`propertyPanels` 等抽象属性,即可在 `onActivate`/`onDeactivate` 中自动完成图形组件、工具栏、属性面板、元素构造器的注册与注销,无需手动 emit 四条事件。
24
+ - **`GraphicRegistryPlugin` 统一注册中心** — 替代原有的 GraphicManagerPlugin、GraphicToolManagerPlugin、ElementManagerPlugin、PropertyPanelManagerPlugin,集中管理所有图形类型、工具栏、属性面板、元素构造器的注册与查询。
25
+
26
+ ### Changed
27
+
28
+ - **字段重命名:`transferable` → `resizable`** — `IGraphicElement` 接口及 `BaseGraphicElement` 实现中的可缩放标记字段统一更名为 `resizable`,语义更准确。
29
+ - **字段重命名:`element.name` → `element.displayName`** — 元素自定义显示名称字段从 `name` 改为 `displayName`,`LayerManagerPlugin` 的自动命名逻辑同步更新。
30
+ - **Rect / Text / Line / Qrcode / Barcode 插件重构** — 五个图形插件从继承 `BasePlugin` + 手动 emit 四条注册事件,改为继承 `GraphicPlugin<T>`,通过抽象属性声明式注册。
31
+ - **方法重命名:`handlePMouseleave` → `handleMouseLeave`** — 统一鼠标离开事件处理方法命名,消除拼写不一致。
32
+ - **`EditorHost` 泛型简化** — `installPlugin` / `getPlugin` / `uninstallPlugin` 方法移除对 `PluginMap` 的泛型依赖,改为运行时 string 键 + 显式泛型重载。
33
+
34
+ ### Deprecated
35
+
36
+ - **`declare module '@/types'` 模块声明合并模式** — 基于 `PluginMap` / `ElementTypeMap` 空接口 + `declare module` 的插件类型注册机制不再推荐使用,改为由 `GraphicPlugin<T>` 及 `GraphicRegistryPlugin` 统一管理类型信息。
37
+
38
+ ### Removed
39
+
40
+ - **删除 `GraphicManagerPlugin`**(`src/plugins/graphic-manager/`)— 功能由 `GraphicRegistryPlugin` 替代。
41
+ - **删除 `GraphicToolManagerPlugin`**(`src/plugins/graphic-tool-manager.ts`)— 功能由 `GraphicRegistryPlugin` 替代。
42
+ - **删除 `ElementManagerPlugin`**(`src/plugins/element-manager.ts`)— 功能由 `GraphicRegistryPlugin` 替代。
43
+ - **删除 `PropertyPanelManagerPlugin`**(`src/plugins/property-panel-manager/`)— 功能由 `GraphicRegistryPlugin` 替代。
44
+ - **删除 `PluginMap` 类型文件**(`src/types/plugin-map.ts`)— 不再需要模块声明合并模式。
45
+ - **删除 `ElementTypeMap` 类型文件**(`src/types/element-type-map.ts`)— 不再需要模块声明合并模式。
46
+ - **删除 `BaseGraphicType` 类型文件**(`src/types/base-graphic-type.ts`)— 由 `GraphicPlugin<T>` 替代。
47
+ - **清理死代码** — 移除 EditorHost 及各个插件中因旧架构残留的临时变量、未使用 imports 及已注释代码块。
48
+
49
+ ### Fixed
50
+
51
+ - **`create-host.ts`** — 修复核心插件安装链,移除已删除的四个旧 Manager 插件引用,替换为 `GraphicRegistryPlugin`。
package/README.en.md CHANGED
@@ -5,26 +5,29 @@
5
5
  [![Node.js](https://img.shields.io/node/v/vkedit?style=flat-square)](package.json)
6
6
  [![Live Demo](https://img.shields.io/badge/Live%20Demo-vkedit.org-orange?style=flat-square)](https://vkedit.org)
7
7
 
8
- A visual canvas designer component built on Vue 3 and Konva.js. Features a plugin-based architecture for label, QR code, barcode, receipt, business card, and certificate template design and print layout.
8
+ A visual canvas designer component built on Vue 3 and Konva.js with a plugin-based architecture, for label, QR code, barcode, receipt, business card, and certificate template design and print layout.
9
9
 
10
10
  **[中文](README.md)** | **[Live Demo](https://vkedit.org)** | **[Docs](https://docs.vkedit.org)**
11
11
 
12
12
  ---
13
13
 
14
- ![Project Preview](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png)
14
+ ![Project Preview](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png?v=3)
15
15
 
16
16
  ---
17
17
 
18
18
  ## Features
19
19
 
20
- - **Plugin-based architecture** - Core features and graphic elements are registered as plugins, enabled on demand
21
- - **7 graphic element types** - Rectangle, text, line, table, QR code, barcode, chart (ECharts)
20
+ - **Plugin-based architecture** - Core features and graphic elements are registered as plugins, enabled on demand; `GraphicPlugin<T>` abstract base class simplifies custom plugin development
21
+ - **5 graphic element types** - Rectangle, text, line, QR code, barcode
22
22
  - **Undo / Redo** - Command pattern, all modifications are reversible
23
23
  - **Import / Export** - JSON serialization, PNG/JPG images, PDF documents
24
24
  - **Align & Distribute** - Left/right/top/bottom/center alignment, horizontal/vertical distribution
25
25
  - **Ruler & Zoom** - Millimeter-precision ruler, configurable DPM (dots per millimeter)
26
26
  - **Event-driven** - Type-safe event system for loosely coupled plugin communication
27
27
  - **TypeScript** - Full type definitions with generic plugin and element type inference
28
+ - **Design Token system** - Two-layer token architecture (palette + semantic), complete CSS variable set for spacing, radius, font, shadow, elevation, z-index
29
+ - **Theme system** - Dark theme by default, light theme via `data-vkedit-theme`; Teleport overlay theme inheritance; `resolveVkeditTheme()` utility
30
+ - **VkButton variants** - primary, destructive, outline, secondary, ghost, link
28
31
 
29
32
  ---
30
33
 
@@ -36,11 +39,11 @@ pnpm add vkedit vue konva vue-konva
36
39
 
37
40
  vkedit declares `vue`, `konva`, and `vue-konva` as peerDependencies, which must be provided by the host project.
38
41
 
39
- | Peer Dependency | Version |
40
- | --------------- | -------- |
41
- | vue | ^3.5.18 |
42
- | konva | ^10.0.2 |
43
- | vue-konva | ^3.2.6 |
42
+ | Peer Dependency | Version |
43
+ | --------------- | ------- |
44
+ | vue | ^3.5.18 |
45
+ | konva | ^10.0.2 |
46
+ | vue-konva | ^3.2.6 |
44
47
 
45
48
  Node.js requirement: `^20.19.0 || >=22.12.0`
46
49
 
@@ -75,10 +78,8 @@ import { createEditorHost, Vkedit } from 'vkedit'
75
78
  import {
76
79
  RectPlugin,
77
80
  TextPlugin,
78
- TablePlugin,
79
81
  QrcodePlugin,
80
82
  BarcodePlugin,
81
- ChartPlugin,
82
83
  LinePlugin,
83
84
  } from 'vkedit'
84
85
 
@@ -88,10 +89,8 @@ const host = createEditorHost()
88
89
  host
89
90
  .installPlugin('rect-plugin', RectPlugin)
90
91
  .installPlugin('text-plugin', TextPlugin)
91
- .installPlugin('table-plugin', TablePlugin)
92
92
  .installPlugin('qr-plugin', QrcodePlugin)
93
93
  .installPlugin('barcode-plugin', BarcodePlugin)
94
- .installPlugin('chart-plugin', ChartPlugin)
95
94
  .installPlugin('line-plugin', LinePlugin)
96
95
 
97
96
  // Set canvas size (A4 paper, DPM = 8)
@@ -108,6 +107,32 @@ host.setStatus({
108
107
 
109
108
  ---
110
109
 
110
+ ## Theme & Styles
111
+
112
+ vkedit ships with a complete Design Token system. The dark theme is enabled by default (`data-vkedit-theme="dark"`). Just import the CSS:
113
+
114
+ ```ts
115
+ import 'vkedit/dist/vkedit.css'
116
+ ```
117
+
118
+ Override the brand color on the editor root or a wrapper container:
119
+
120
+ ```css
121
+ .vkedit-editor {
122
+ --vkedit-color-primary: oklch(70% 0.14 185);
123
+ --vkedit-color-primary-hover: oklch(78% 0.12 185);
124
+ --vkedit-color-on-primary: oklch(14% 0 0);
125
+ }
126
+ ```
127
+
128
+ The token system has two layers:
129
+ - **Palette** (`:root`) — raw color scales (neutral, teal, danger, etc.) and non-color tokens (spacing, radius, font, shadow, elevation, z-index)
130
+ - **Semantic** (theme selector) — meaningful variable names that reference palette values, defined for both `data-vkedit-theme="dark"` (default) and `data-vkedit-theme="light"`
131
+
132
+ See [MIGRATION.md](./MIGRATION.md) for the full variable list and breaking changes.
133
+
134
+ ---
135
+
111
136
  ## Links
112
137
 
113
138
  - [Website](https://vkedit.org)
@@ -132,26 +157,3 @@ host.setStatus({
132
157
  - **Email**: 168715824@qq.com
133
158
 
134
159
  Available for technical support, custom features, and project collaboration.
135
-
136
- ---
137
-
138
- ## Sponsor
139
-
140
- If vkedit helps you, consider buying the author a coffee.
141
-
142
- <div align="center">
143
-
144
- <table>
145
- <tr>
146
- <td align="center">
147
- <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-alipay.png" width="200" alt="Alipay" />
148
- <br>Alipay
149
- </td>
150
- <td align="center">
151
- <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-wechat.png" width="200" alt="WeChat Pay" />
152
- <br>WeChat
153
- </td>
154
- </tr>
155
- </table>
156
-
157
- </div>
package/README.md CHANGED
@@ -11,20 +11,23 @@
11
11
 
12
12
  ---
13
13
 
14
- ![项目预览](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png)
14
+ ![项目预览](https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/image.png?v=3)
15
15
 
16
16
  ---
17
17
 
18
18
  ## 特性
19
19
 
20
- - **插件化架构** - 核心功能与图形元素均以插件形式注册,按需启用
21
- - **7 种图形元素** - 矩形、文本、线条、表格、二维码、条形码、图表(ECharts)
20
+ - **插件化架构** - 核心功能与图形元素均以插件形式注册,按需启用;`GraphicPlugin<T>` 抽象基类简化自定义插件开发
21
+ - **5 种图形元素** - 矩形、文本、线条、二维码、条形码
22
22
  - **撤销/重做** - 基于命令模式,所有修改操作可逆
23
23
  - **导入/导出** - JSON 序列化、PNG/JPG 图片、PDF 文档
24
24
  - **对齐与分布** - 左/右/上/下/居中对齐、水平/垂直均分
25
25
  - **标尺与缩放** - 毫米级精度标尺、可配置 DPM(每毫米点数)
26
26
  - **事件驱动** - 类型安全的事件系统,插件间松耦合通信
27
27
  - **TypeScript** - 完整类型定义,泛型推断插件与元素类型
28
+ - **设计令牌系统** - 两层架构(Palette + Semantic),完整 CSS 变量覆盖 spacing、radius、font、shadow、elevation、z-index
29
+ - **主题系统** - 默认暗色主题,亮色主题通过 `data-vkedit-theme` 切换;Teleport 浮层主题继承;`resolveVkeditTheme()` 工具函数
30
+ - **VkButton 多变体** - primary、destructive、outline、secondary、ghost、link
28
31
 
29
32
  ---
30
33
 
@@ -75,10 +78,8 @@ import { createEditorHost, Vkedit } from 'vkedit'
75
78
  import {
76
79
  RectPlugin,
77
80
  TextPlugin,
78
- TablePlugin,
79
81
  QrcodePlugin,
80
82
  BarcodePlugin,
81
- ChartPlugin,
82
83
  LinePlugin,
83
84
  } from 'vkedit'
84
85
 
@@ -88,10 +89,8 @@ const host = createEditorHost()
88
89
  host
89
90
  .installPlugin('rect-plugin', RectPlugin)
90
91
  .installPlugin('text-plugin', TextPlugin)
91
- .installPlugin('table-plugin', TablePlugin)
92
92
  .installPlugin('qr-plugin', QrcodePlugin)
93
93
  .installPlugin('barcode-plugin', BarcodePlugin)
94
- .installPlugin('chart-plugin', ChartPlugin)
95
94
  .installPlugin('line-plugin', LinePlugin)
96
95
 
97
96
  // 设置画布尺寸(A4 纸张,DPM = 8)
@@ -108,6 +107,32 @@ host.setStatus({
108
107
 
109
108
  ---
110
109
 
110
+ ## 主题与样式
111
+
112
+ vkedit 内置完整的设计令牌(Design Token)体系。暗色主题为默认值(`data-vkedit-theme="dark"`),引入 CSS 后即刻生效:
113
+
114
+ ```ts
115
+ import 'vkedit/dist/vkedit.css'
116
+ ```
117
+
118
+ 覆盖品牌色(挂载在编辑器根或包裹容器上):
119
+
120
+ ```css
121
+ .vkedit-editor {
122
+ --vkedit-color-primary: oklch(70% 0.14 185);
123
+ --vkedit-color-primary-hover: oklch(78% 0.12 185);
124
+ --vkedit-color-on-primary: oklch(14% 0 0);
125
+ }
126
+ ```
127
+
128
+ 令牌体系分两层:
129
+ - **Palette**(`:root`)— 颜色原始阶梯(neutral、teal、danger 等)以及非颜色尺度(spacing、radius、font、shadow、elevation、z-index)
130
+ - **Semantic**(主题选择器)— 引用 palette 的语义变量,分别定义 `data-vkedit-theme="dark"`(默认)与 `data-vkedit-theme="light"` 两套映射
131
+
132
+ 完整变量列表与破坏性变更说明见 [MIGRATION.md](./MIGRATION.md)。
133
+
134
+ ---
135
+
111
136
  ## 链接
112
137
 
113
138
  - [官网](https://vkedit.org)
@@ -132,24 +157,3 @@ host.setStatus({
132
157
  - **邮箱**: 168715824@qq.com
133
158
 
134
159
  提供技术支持、功能定制、项目合作。
135
-
136
- ---
137
-
138
- 如果 vkedit 对您有帮助,欢迎请作者喝杯咖啡。
139
-
140
- <div align="center">
141
-
142
- <table>
143
- <tr>
144
- <td align="center">
145
- <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-alipay.png" width="200" alt="支付宝打赏" />
146
- <br>支付宝
147
- </td>
148
- <td align="center">
149
- <img src="https://raw.githubusercontent.com/pwg-code/vkedit/main/截图/reward-wechat.png" width="200" alt="微信打赏" />
150
- <br>微信
151
- </td>
152
- </tr>
153
- </table>
154
-
155
- </div>
@@ -5,6 +5,7 @@ export declare class ChangeLayerOrderCommand extends BaseCommand {
5
5
  private direction;
6
6
  name: string;
7
7
  private previousOrder;
8
+ private elementsPlugin;
8
9
  constructor(host: EditorHost, elementId: string, direction: 'up' | 'down' | 'top' | 'bottom');
9
10
  execute(): void;
10
11
  undo(): void;
@@ -7,6 +7,7 @@ export * from './update-property-command';
7
7
  export * from './clear-selection-command';
8
8
  export * from './batch-command';
9
9
  export * from './change-layer-order-command';
10
+ export * from './reorder-elements-command';
10
11
  export * from './align-elements-command';
11
12
  export * from './distribute-elements-command';
12
13
  export * from './clear-selection-command';
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from './base-command';
2
+ import { EditorHost } from '../core';
3
+ /**
4
+ * 批量重排命令:用于图层列表拖拽松手后一次性重建全局顺序。
5
+ * 入参 newOrder 为元素 id 列表,按拖拽后的完整新顺序自顶到底层传入。
6
+ * execute:按 newOrder 重新分配 zIndex,第 i 个元素 zIndex = newOrder.length - i(保证顶部最大)。
7
+ * undo:恢复快照中保存的 previousOrder(原始全局 id → zIndex 映射)。
8
+ */
9
+ export declare class ReorderElementsCommand extends BaseCommand {
10
+ private newOrder;
11
+ name: string;
12
+ private elementsPlugin;
13
+ private previousOrder;
14
+ constructor(host: EditorHost, newOrder: string[], description?: string);
15
+ execute(): void;
16
+ undo(): void;
17
+ private saveCurrentOrder;
18
+ private applyOrder;
19
+ }
@@ -5,5 +5,32 @@ interface Props {
5
5
  element: BaseGraphicElement;
6
6
  selection: BaseGraphicElement[];
7
7
  }
8
- declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
8
+ declare const _default: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
9
+ nameInputEl: import('vue').CreateComponentPublicInstanceWithMixins<Readonly<{
10
+ modelValue?: string | number;
11
+ defaultValue?: string | number;
12
+ class?: import('vue').HTMLAttributes["class"];
13
+ }> & Readonly<{
14
+ "onUpdate:modelValue"?: ((payload: string | number) => any) | undefined;
15
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
16
+ "update:modelValue": (payload: string | number) => any;
17
+ }, import('vue').PublicProps, {
18
+ defaultValue: string | number;
19
+ }, false, {}, {}, import('vue').GlobalComponents, import('vue').GlobalDirectives, string, {}, HTMLInputElement, import('vue').ComponentProvideOptions, {
20
+ P: {};
21
+ B: {};
22
+ D: {};
23
+ C: {};
24
+ M: {};
25
+ Defaults: {};
26
+ }, Readonly<{
27
+ modelValue?: string | number;
28
+ defaultValue?: string | number;
29
+ class?: import('vue').HTMLAttributes["class"];
30
+ }> & Readonly<{
31
+ "onUpdate:modelValue"?: ((payload: string | number) => any) | undefined;
32
+ }>, {}, {}, {}, {}, {
33
+ defaultValue: string | number;
34
+ }> | null;
35
+ }, any>;
9
36
  export default _default;
@@ -2,6 +2,8 @@ import { EditorHost } from '../core';
2
2
  import { IAlign, IFontStyle, IVerticalAlign } from '../types';
3
3
  type __VLS_Props = {
4
4
  host: EditorHost;
5
+ text?: string;
6
+ fill?: string;
5
7
  fontSize: number;
6
8
  align: IAlign;
7
9
  verticalAlign: IVerticalAlign;
@@ -1,5 +1,5 @@
1
1
  import { HTMLAttributes } from 'vue';
2
- type ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
2
+ type ButtonVariant = 'default' | 'primary' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';
3
3
  type ButtonSize = 'default' | 'xs' | 'sm' | 'lg' | 'icon' | 'icon-sm' | 'icon-lg';
4
4
  type __VLS_Props = {
5
5
  variant?: ButtonVariant;
@@ -18,8 +18,8 @@ declare function __VLS_template(): {
18
18
  };
19
19
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
20
20
  declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
21
- variant: ButtonVariant;
22
21
  size: ButtonSize;
22
+ variant: ButtonVariant;
23
23
  disabled: boolean;
24
24
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLButtonElement>;
25
25
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
@@ -0,0 +1,26 @@
1
+ type __VLS_Props = {
2
+ modelValue?: string | null;
3
+ label?: string;
4
+ allowNone?: boolean;
5
+ disabled?: boolean;
6
+ warning?: string;
7
+ errorMessage?: string;
8
+ swatches?: string[];
9
+ };
10
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
11
+ "update:modelValue": (value: string | null) => any;
12
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
13
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
14
+ }>, {
15
+ disabled: boolean;
16
+ modelValue: string | null;
17
+ allowNone: boolean;
18
+ warning: string;
19
+ errorMessage: string;
20
+ swatches: string[];
21
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
22
+ rootRef: HTMLDivElement;
23
+ hexInput: HTMLInputElement;
24
+ nativePicker: HTMLInputElement;
25
+ }, HTMLDivElement>;
26
+ export default _default;
@@ -0,0 +1,20 @@
1
+ import { HTMLAttributes } from 'vue';
2
+ type __VLS_Props = {
3
+ modelValue: string;
4
+ rows?: number;
5
+ placeholder?: string;
6
+ disabled?: boolean;
7
+ class?: HTMLAttributes['class'];
8
+ };
9
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
10
+ "update:modelValue": (value: string) => any;
11
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
13
+ }>, {
14
+ disabled: boolean;
15
+ placeholder: string;
16
+ rows: number;
17
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
18
+ textareaRef: HTMLTextAreaElement;
19
+ }, HTMLTextAreaElement>;
20
+ export default _default;
@@ -8,4 +8,5 @@ export { default as VkInputMM } from './VkInputMM.vue';
8
8
  export { default as VkInputNumberMM } from './VkInputNumberMM.vue';
9
9
  export { default as VkInputNumber } from './VkInputNumber.vue';
10
10
  export { default as VkDropdown } from './VkDropdown.vue';
11
- export { default as VkIcon } from './VkIcon.vue';
11
+ export { default as VkColorPicker } from './VkColorPicker.vue';
12
+ export { default as VkTextarea } from './VkTextarea.vue';
@@ -10,7 +10,6 @@ declare function __VLS_template(): {
10
10
  refs: {
11
11
  contentLayerRef: unknown;
12
12
  groupRef: unknown;
13
- transformerRef: unknown;
14
13
  };
15
14
  rootEl: any;
16
15
  };
@@ -18,7 +17,6 @@ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
18
17
  declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
19
18
  contentLayerRef: unknown;
20
19
  groupRef: unknown;
21
- transformerRef: unknown;
22
20
  }, any>;
23
21
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
24
22
  export default _default;
@@ -4,6 +4,7 @@ type __VLS_Props = {
4
4
  showToolbox?: boolean;
5
5
  showPropertyPanel?: boolean;
6
6
  showToolbar?: boolean;
7
+ showLayers?: boolean;
7
8
  };
8
9
  declare function __VLS_template(): {
9
10
  attrs: Partial<{}>;
@@ -1,5 +1,10 @@
1
- import { EditorHost } from '../../core';
1
+ import { EditorHost } from '.';
2
+ import { IGraphicElement } from '../types';
2
3
  type __VLS_Props = {
4
+ type: string;
5
+ iconComponent: any;
6
+ typeDisplayName: string;
7
+ createElement: () => IGraphicElement;
3
8
  host: EditorHost;
4
9
  collapsed?: boolean;
5
10
  };
@@ -1,2 +1,4 @@
1
- declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, HTMLDivElement>;
1
+ declare const _default: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
2
+ helpGuideRef: HTMLDivElement;
3
+ }, HTMLDivElement>;
2
4
  export default _default;
@@ -1,6 +1,6 @@
1
- import { TableElement } from './table';
1
+ import { EditorHost } from '.';
2
2
  type __VLS_Props = {
3
- element: TableElement;
3
+ host: EditorHost;
4
4
  };
5
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, {}, any>;
6
6
  export default _default;
@@ -1,6 +1,5 @@
1
- import { IEditorPlugin, IEditorState, EventMap, PluginMap } from '../types';
1
+ import { IEditorPlugin, IEditorState, EventMap } from '../types';
2
2
  import { ICommand } from '../commands/i-command';
3
- import { RectPlugin } from '../plugins';
4
3
  export declare class EditorHost {
5
4
  private plugins;
6
5
  private events;
@@ -25,11 +24,8 @@ export declare class EditorHost {
25
24
  emit<K extends keyof EventMap>(event: K, payload: Parameters<EventMap[K]>[0]): void;
26
25
  on<K extends keyof EventMap>(event: K, handler: EventMap[K]): void;
27
26
  off<K extends keyof EventMap>(event: K, handler: EventMap[K]): void;
28
- installPlugin<K extends keyof PluginMap>(name: K, pluginClass: PluginMap[K] | (new (...args: any[]) => PluginMap[K])): EditorHost;
29
- installPlugin(name: string, pluginClass: IEditorPlugin | (new (...args: any[]) => IEditorPlugin)): EditorHost;
30
- uninstallPlugin<K extends keyof PluginMap>(pluginName: K): EditorHost;
27
+ installPlugin<T extends IEditorPlugin = IEditorPlugin>(name: string, pluginClass: new (...args: any[]) => T): EditorHost;
31
28
  uninstallPlugin(pluginName: string): EditorHost;
32
- getPlugin<K extends keyof PluginMap>(pluginName: K): PluginMap[K];
33
29
  getPlugin<T extends IEditorPlugin = IEditorPlugin>(pluginName: string): T;
34
30
  executeCommand(command: ICommand): void;
35
31
  undo(): void;
@@ -39,8 +35,3 @@ export declare class EditorHost {
39
35
  toJSON(): string;
40
36
  loadJSON(jsonStr: string): void;
41
37
  }
42
- declare module '../types' {
43
- interface PluginMap {
44
- ttt: RectPlugin;
45
- }
46
- }
package/dist/favicon.ico CHANGED
Binary file
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="vkedit">
3
+ <title>vkedit</title>
4
+ <desc>Teal rounded square with a fused white VK monogram. V's right arm and K's vertical stem share the same axis (x=30 to 36), so the lower half of the K stem is absorbed into V. The K diagonals branch from that shared stem to the upper-right and lower-right corners of the mark.</desc>
5
+ <rect width="64" height="64" rx="14" fill="#0d9488"/>
6
+ <path d="M 8 14 L 20 14 L 32 40 L 44 14 L 56 14 L 36 52 L 28 52 Z" fill="#ffffff"/>
7
+ <path d="M 30 14 L 36 14 L 36 28 L 50 14 L 56 14 L 40 32 L 56 50 L 50 50 L 36 36 L 36 50 L 30 50 Z" fill="#ffffff"/>
8
+ </svg>
@@ -7,3 +7,4 @@ export * from './use-selection-layer';
7
7
  export * from './use-stage-event';
8
8
  export * from './use-stage';
9
9
  export * from './use-zoom';
10
+ export * from './use-transform-overlay';
@@ -2,7 +2,6 @@ import { IGraphicElement } from '../types';
2
2
  import { EditorHost } from '../core';
3
3
  export declare function useContentLayer(host: EditorHost): {
4
4
  contentLayerRef: import('vue').Ref<any, any>;
5
- transformerRef: import('vue').Ref<any, any>;
6
5
  contentLayerConfig: import('vue').ComputedRef<{}>;
7
6
  contentGroupConfig: import('vue').ComputedRef<{
8
7
  x: number;
@@ -23,7 +22,9 @@ export declare function useContentLayer(host: EditorHost): {
23
22
  visible: boolean;
24
23
  locked: boolean;
25
24
  draggable: boolean;
26
- transferable: boolean;
25
+ resizable: boolean;
26
+ zIndex: number;
27
+ displayName?: string | null | undefined;
27
28
  resizeAnchors?: string[] | null | undefined;
28
29
  getBoundingBox: () => import('../types').BoundingBox;
29
30
  clone: () => IGraphicElement;
@@ -47,7 +48,9 @@ export declare function useContentLayer(host: EditorHost): {
47
48
  visible: boolean;
48
49
  locked: boolean;
49
50
  draggable: boolean;
50
- transferable: boolean;
51
+ resizable: boolean;
52
+ zIndex: number;
53
+ displayName?: string | null | undefined;
51
54
  resizeAnchors?: string[] | null | undefined;
52
55
  getBoundingBox: () => import('../types').BoundingBox;
53
56
  clone: () => IGraphicElement;
@@ -63,8 +66,5 @@ export declare function useContentLayer(host: EditorHost): {
63
66
  handleDragStart: (event: any, element: any) => void;
64
67
  handleDragMove: (event: any, element: any) => void;
65
68
  handleDragEnd: (event: any, element: any) => void;
66
- handleElementTransform: (event: any, element: IGraphicElement) => void;
67
- handleElementTransformEnd: (event: any, element: any) => void;
68
- updateTransformerNodes: (selection: IGraphicElement[]) => void;
69
69
  updateCanvas: () => void;
70
70
  };
@@ -4,6 +4,7 @@ export declare function useHostState(host: EditorHost): {
4
4
  zoom: number;
5
5
  currentTool: string;
6
6
  snapToGrid: boolean;
7
+ snapRotation: boolean;
7
8
  showGrid: boolean;
8
9
  width: number;
9
10
  height: number;
@@ -24,6 +24,30 @@ export declare function useRulerLayer(host: EditorHost): {
24
24
  strokeWidth: number;
25
25
  listening: boolean;
26
26
  }>;
27
+ cornerConfig: import('vue').ComputedRef<{
28
+ x: number;
29
+ y: number;
30
+ width: number;
31
+ height: number;
32
+ fill: string;
33
+ strokeEnabled: boolean;
34
+ listening: boolean;
35
+ }>;
36
+ cornerEdgeConfigs: import('vue').ComputedRef<{
37
+ right: {
38
+ points: number[];
39
+ stroke: string;
40
+ strokeWidth: number;
41
+ listening: boolean;
42
+ };
43
+ bottom: {
44
+ points: number[];
45
+ stroke: string;
46
+ strokeWidth: number;
47
+ listening: boolean;
48
+ };
49
+ }>;
27
50
  upRulerShapeRef: import('vue').Ref<any, any>;
28
51
  leftRulerShapeRef: import('vue').Ref<any, any>;
52
+ RULER_SIZE: number;
29
53
  };
@@ -18,8 +18,8 @@ export declare function useSelectionLayer(host: EditorHost): {
18
18
  }>;
19
19
  handleMouseDown: (event: any) => void;
20
20
  handleMouseMove: (event: any) => void;
21
- handleMouseUp: (event: any) => void;
22
- handlePMouseleave: (event: any) => void;
21
+ handleMouseUp: () => void;
22
+ handleMouseLeave: () => void;
23
23
  rectConfig: import('vue').ComputedRef<{
24
24
  x: number;
25
25
  y: number;
@@ -28,7 +28,6 @@ export declare function useSelectionLayer(host: EditorHost): {
28
28
  fill: string;
29
29
  stroke: string;
30
30
  strokeWidth: number;
31
- dash: number[];
32
31
  listening: boolean;
33
32
  }>;
34
33
  selectionLayerConfig: import('vue').Ref<{}, {}>;