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.
- package/CHANGELOG.md +51 -0
- package/README.en.md +38 -36
- package/README.md +32 -28
- package/dist/commands/change-layer-order-command.d.ts +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/reorder-elements-command.d.ts +19 -0
- package/dist/components/BaseElementPropertyPanel.vue.d.ts +28 -1
- package/dist/components/TextProperty.vue.d.ts +2 -0
- package/dist/components/ui/VkButton.vue.d.ts +2 -2
- package/dist/components/ui/VkColorPicker.vue.d.ts +26 -0
- package/dist/components/ui/VkTextarea.vue.d.ts +20 -0
- package/dist/components/ui/index.d.ts +2 -1
- package/dist/core/ContentLayer.vue.d.ts +0 -2
- package/dist/core/Editor.vue.d.ts +1 -0
- package/dist/{plugins/rect/Tool.vue.d.ts → core/GraphicToolRenderer.vue.d.ts} +6 -1
- package/dist/core/HelpGuide.vue.d.ts +3 -1
- package/dist/{plugins/table/CellsBorder.vue.d.ts → core/TransformOverlay.vue.d.ts} +2 -2
- package/dist/core/editor-host.d.ts +2 -11
- package/dist/favicon.ico +0 -0
- package/dist/favicon.svg +8 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/use-content-layer.d.ts +6 -6
- package/dist/hooks/use-host-state.d.ts +1 -0
- package/dist/hooks/use-ruler-layer.d.ts +24 -0
- package/dist/hooks/use-selection-layer.d.ts +2 -3
- package/dist/hooks/use-stage-event.d.ts +1 -0
- package/dist/hooks/use-transform-overlay.d.ts +108 -0
- package/dist/index-CSKpw1uX.js +25597 -0
- package/dist/{index.es-B1gCGYT7.js → index.es-Dswe047Z.js} +1 -1
- package/dist/plugins/barcode/Shape.vue.d.ts +1 -1
- package/dist/plugins/barcode/barcode.d.ts +12 -13
- package/dist/plugins/barcode/index.d.ts +0 -1
- package/dist/plugins/export/export.d.ts +1 -2
- package/dist/plugins/graphic-registry/graphic-registry.d.ts +43 -0
- package/dist/plugins/graphic-registry/index.d.ts +1 -0
- package/dist/plugins/import/import.d.ts +1 -2
- package/dist/plugins/index.d.ts +2 -6
- package/dist/plugins/{table/ContextMenu.vue.d.ts → layer-manager/LayerPanel.vue.d.ts} +5 -4
- package/dist/plugins/layer-manager/index.d.ts +2 -0
- package/dist/plugins/layer-manager/layer-manager.d.ts +16 -0
- package/dist/plugins/line/Shape.vue.d.ts +1 -1
- package/dist/plugins/line/index.d.ts +0 -1
- package/dist/plugins/line/line.d.ts +12 -13
- package/dist/plugins/qrcode/Shape.vue.d.ts +1 -1
- package/dist/plugins/qrcode/index.d.ts +0 -1
- package/dist/plugins/qrcode/qrcode.d.ts +12 -13
- package/dist/plugins/rect/Shape.vue.d.ts +1 -1
- package/dist/plugins/rect/index.d.ts +0 -1
- package/dist/plugins/rect/rect.d.ts +11 -13
- package/dist/plugins/selection.d.ts +0 -1
- package/dist/plugins/text/Shape.vue.d.ts +1 -1
- package/dist/plugins/text/index.d.ts +0 -1
- package/dist/plugins/text/text.d.ts +16 -13
- package/dist/types/base-graphic-element.d.ts +10 -3
- package/dist/types/base.d.ts +5 -18
- package/dist/types/event-data.d.ts +17 -0
- package/dist/types/event-map.d.ts +8 -1
- package/dist/types/graphic-plugin.d.ts +27 -0
- package/dist/types/index.d.ts +1 -3
- package/dist/utils/color.d.ts +40 -0
- package/dist/utils/css-var.d.ts +14 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/readability.d.ts +22 -0
- package/dist/utils/theme.d.ts +2 -0
- package/dist/utils/transform-geometry.d.ts +62 -0
- package/dist/utils/transform-overlay.d.ts +62 -0
- package/dist/vkedit.css +1 -1
- package/dist/vkedit.es.js +81 -96
- package/package.json +4 -5
- package/dist/components/ui/VkIcon.vue.d.ts +0 -8
- package/dist/index-Aa1HXlw6.js +0 -72887
- package/dist/plugins/barcode/Tool.vue.d.ts +0 -6
- package/dist/plugins/chart/PropertyPanel.vue.d.ts +0 -9
- package/dist/plugins/chart/Shape.vue.d.ts +0 -23
- package/dist/plugins/chart/Tool.vue.d.ts +0 -6
- package/dist/plugins/chart/chart.d.ts +0 -38
- package/dist/plugins/chart/index.d.ts +0 -4
- package/dist/plugins/element-manager.d.ts +0 -24
- package/dist/plugins/graphic-manager/graphic-manager.d.ts +0 -31
- package/dist/plugins/graphic-manager/index.d.ts +0 -1
- package/dist/plugins/graphic-tool-manager.d.ts +0 -16
- package/dist/plugins/line/Tool.vue.d.ts +0 -7
- package/dist/plugins/property-panel-manager/index.d.ts +0 -1
- package/dist/plugins/property-panel-manager/property-panel-manager.d.ts +0 -32
- package/dist/plugins/qrcode/Tool.vue.d.ts +0 -6
- package/dist/plugins/table/PropertyPanel.vue.d.ts +0 -9
- package/dist/plugins/table/Shape.vue.d.ts +0 -26
- package/dist/plugins/table/Tool.vue.d.ts +0 -7
- package/dist/plugins/table/cell.d.ts +0 -61
- package/dist/plugins/table/index.d.ts +0 -6
- package/dist/plugins/table/table.d.ts +0 -92
- package/dist/plugins/text/Tool.vue.d.ts +0 -6
- package/dist/types/base-graphic-type.d.ts +0 -9
- package/dist/types/element-type-map.d.ts +0 -12
- 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
|
[](package.json)
|
|
6
6
|
[](https://vkedit.org)
|
|
7
7
|
|
|
8
|
-
A visual canvas designer component built on Vue 3 and Konva.js
|
|
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
|
-

|
|
14
|
+

|
|
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
|
-
- **
|
|
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
|
-

|
|
14
|
+

|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
18
|
## 特性
|
|
19
19
|
|
|
20
|
-
- **插件化架构** -
|
|
21
|
-
- **
|
|
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;
|
package/dist/commands/index.d.ts
CHANGED
|
@@ -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, {
|
|
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;
|
|
@@ -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
|
|
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;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import { EditorHost } from '
|
|
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, {
|
|
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 {
|
|
1
|
+
import { EditorHost } from '.';
|
|
2
2
|
type __VLS_Props = {
|
|
3
|
-
|
|
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
|
|
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<
|
|
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
|
package/dist/favicon.svg
ADDED
|
@@ -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>
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
};
|
|
@@ -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: (
|
|
22
|
-
|
|
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<{}, {}>;
|