@worm-vue3-print/common 0.0.0-stage → 1.4.0-beta.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 (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -2
  3. package/dist/browser-bundle.d.ts +14 -0
  4. package/dist/common.css +526 -0
  5. package/dist/common.js +1017 -0
  6. package/dist/core/default-template.d.ts +9 -0
  7. package/dist/core/format.d.ts +122 -0
  8. package/dist/core/h.d.ts +22 -0
  9. package/dist/core/icons.d.ts +10 -0
  10. package/dist/core/store.d.ts +163 -0
  11. package/dist/index.cjs +760 -0
  12. package/dist/index.d.ts +13 -0
  13. package/dist/index.js +7697 -0
  14. package/dist/print-designer.d.ts +187 -0
  15. package/dist/shell/binding.d.ts +21 -0
  16. package/dist/shell/canvas.d.ts +59 -0
  17. package/dist/shell/code.d.ts +11 -0
  18. package/dist/shell/color-picker.d.ts +44 -0
  19. package/dist/shell/controls.d.ts +138 -0
  20. package/dist/shell/crop-anchor.d.ts +29 -0
  21. package/dist/shell/elements.d.ts +27 -0
  22. package/dist/shell/expression-editor.d.ts +33 -0
  23. package/dist/shell/flow-list.d.ts +11 -0
  24. package/dist/shell/font-select.d.ts +24 -0
  25. package/dist/shell/format-bar.d.ts +15 -0
  26. package/dist/shell/help-content/changelog.d.ts +12 -0
  27. package/dist/shell/help-content/faq.d.ts +12 -0
  28. package/dist/shell/help-content/features.d.ts +12 -0
  29. package/dist/shell/help-content/getting-started.d.ts +12 -0
  30. package/dist/shell/help-content/index.d.ts +13 -0
  31. package/dist/shell/help-content/shortcuts.d.ts +12 -0
  32. package/dist/shell/help-modal.d.ts +19 -0
  33. package/dist/shell/page-extras.d.ts +11 -0
  34. package/dist/shell/panels.d.ts +17 -0
  35. package/dist/shell/prop-group.d.ts +11 -0
  36. package/dist/shell/property-panel.d.ts +15 -0
  37. package/dist/shell/property-search.d.ts +32 -0
  38. package/dist/shell/ruler.d.ts +29 -0
  39. package/dist/shell/table-props.d.ts +17 -0
  40. package/dist/shell/table.d.ts +22 -0
  41. package/dist/shell/toolbar-overflow.d.ts +28 -0
  42. package/dist/shell/toolbar.d.ts +8 -0
  43. package/dist/shell/watermark.d.ts +11 -0
  44. package/package.json +61 -4
@@ -0,0 +1,9 @@
1
+ /*!
2
+ * @worm-vue3-print/common v1.4.0-beta.0
3
+ * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
+ * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ import type { TemplateData } from '@worm-vue3-print/core/designer';
8
+ /** 默认模板:与 canvas 的 createDefaultTemplate 同结构,保证两侧序列化一致 */
9
+ export declare function createDefaultTemplate(): TemplateData;
@@ -0,0 +1,122 @@
1
+ /*!
2
+ * @worm-vue3-print/common v1.4.0-beta.0
3
+ * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
+ * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ import type { RuntimeElement, TextAlign, VerticalAlign, TableCellBorder } from '@worm-vue3-print/core/designer';
8
+ import { type BorderPreset, type ElementBorderSpec } from '@worm-vue3-print/core/designer';
9
+ import type { DesignerStore } from './store';
10
+ /** 多选目标间字段值不一致的哨兵 */
11
+ export declare const MIXED: unique symbol;
12
+ export type MixedOr<T> = T | typeof MIXED;
13
+ /** 支持字体/对齐等文本样式的元素类型(与 AppearanceGroup 的 isTextType 口径一致) */
14
+ export declare const TEXT_TYPES: Set<string>;
15
+ export interface FormatStylePatch {
16
+ fontFamily?: string;
17
+ fontSize?: number;
18
+ color?: string;
19
+ backgroundColor?: string;
20
+ textAlign?: TextAlign;
21
+ verticalAlign?: VerticalAlign;
22
+ }
23
+ /** 元素边框规格:类型与写入口径都在 core,本包不再自造一份 */
24
+ export type { ElementBorderSpec };
25
+ type BorderSide = 'top' | 'right' | 'bottom' | 'left';
26
+ export declare class FormatToolbar {
27
+ private store;
28
+ /** 线型草稿:null = 一个格式都没选中(线型=无,点预设/单边即按「无」落盘) */
29
+ borderStyle: 'solid' | 'dashed' | 'dotted' | 'double' | null;
30
+ /** 多选/混合态允许留空;批写时按缺省档兜底 */
31
+ borderWidth: number | undefined;
32
+ borderColor: string | undefined;
33
+ /** 单元格四边规格不一致的字段:留空、不谎报;未选时批写按缺省档 */
34
+ borderMixed: {
35
+ style: boolean;
36
+ width: boolean;
37
+ color: boolean;
38
+ };
39
+ /** 最近一次已回读的单元格选区标识:只在新选区回填,避免每次重绘冲掉用户草稿 */
40
+ private borderDraftKey;
41
+ get borderMixedAny(): boolean;
42
+ painterActive: boolean;
43
+ painterLocked: boolean;
44
+ painterSource: string | null;
45
+ private painterSnapshot;
46
+ constructor(store: DesignerStore);
47
+ private get selectedElements();
48
+ private get tableElement();
49
+ get context(): 'none' | 'cells' | 'elements';
50
+ /** 选区内的可写单元格(跳过被合并占位格) */
51
+ private get targetCells();
52
+ /** 字体/字号/颜色/对齐仅对文本类元素生效 */
53
+ private get textTargets();
54
+ get fontEditable(): boolean;
55
+ /** 文本类写入目标:单元格上下文为选区单元格,元素上下文为文本类选中元素 */
56
+ private get styleTargets();
57
+ private pick;
58
+ private hasToken;
59
+ get values(): {
60
+ fontFamily?: MixedOr<string>;
61
+ fontSize?: MixedOr<number>;
62
+ color?: MixedOr<string>;
63
+ backgroundColor?: MixedOr<string>;
64
+ textAlign?: MixedOr<TextAlign>;
65
+ verticalAlign?: MixedOr<VerticalAlign>;
66
+ bold: MixedOr<boolean>;
67
+ underline: MixedOr<boolean>;
68
+ strike: MixedOr<boolean>;
69
+ };
70
+ /** 落历史并通知视图(时机与 Vue 版 recordHistory 调用点一一对应) */
71
+ private commit;
72
+ private writeCells;
73
+ applyStyle(patch: FormatStylePatch): void;
74
+ toggleBold(): void;
75
+ private toggleDecoration;
76
+ toggleUnderline(): void;
77
+ toggleStrike(): void;
78
+ /**
79
+ * 单元格上下文的三行回读:单格取该格真实规格(四边不一致的字段留空并标 mixed);
80
+ * 多选按上一轮口径不取单格,落缺省档作批写源。只在选区变化时回填,用户改草稿不会被打断。
81
+ */
82
+ syncBorderDraft(): void;
83
+ /** 当前面板草稿对应的边框规格(Vue 版组件内 borderSpec());混合/留空项按缺省档兜底 */
84
+ borderSpec(): TableCellBorder;
85
+ setBorderWidth(v: number | undefined): void;
86
+ setBorderColor(v: string | undefined): void;
87
+ /** 单元格批写落盘后本次规格已统一:混合标记与留空项落定为实际写入值 */
88
+ private settleBorderDraft;
89
+ /** 再点已选中的线型=取消该格式(图标全不亮=线型无) */
90
+ toggleBorderStyle(key: 'solid' | 'dashed' | 'dotted' | 'double'): void;
91
+ private applyElementBorder;
92
+ private applyCellBorderPreset;
93
+ private applyCellBorderEdges;
94
+ /** 单元格选区四边激活态(WPS 式单边按钮的按下态);非单元格上下文或选区为空为 null */
95
+ get cellEdges(): Record<BorderSide, MixedOr<boolean>> | null;
96
+ /** 单边切换:未全有则补齐该边,全有再点则移除该边(与 Word/WPS 一致) */
97
+ private toggleCellEdge;
98
+ /** 元素选中集的分边激活态:看「这条边到底有没有线」(整圈生效=四边都有),与属性台勾选框同一判据 */
99
+ get elementEdges(): Record<BorderSide, MixedOr<boolean>> | null;
100
+ /** 元素分边切换:勾上用面板草稿;整圈生效时撤一边会把其余三边展开成分边 */
101
+ private toggleElementEdge;
102
+ /** 边框预设(Vue 版组件 onPreset 的路由口径):单元格上下文走表格预设,否则走元素整圈 */
103
+ applyBorderPreset(preset: BorderPreset): void;
104
+ /** 单边按钮(Vue 版组件 onEdge 的路由口径):按上下文落到单元格边或元素分边 */
105
+ applyEdge(side: BorderSide): void;
106
+ /** 撤掉一条边(线型=无时工具栏的单边走这条):整圈生效时其余三边展开成单边 */
107
+ private clearElementEdge;
108
+ /** 单边按下态(Vue 版组件 edgeOn 口径) */
109
+ edgeOn(side: BorderSide): boolean;
110
+ /** 仅选中单个未锁定元素时可作为格式源 */
111
+ get painterCapturable(): boolean;
112
+ private clonePainterBorders;
113
+ /** 从当前唯一选中元素捕获格式并进入刷取模式;locked=true 为双击连续刷 */
114
+ pickPainterSource(nextLocked?: boolean): boolean;
115
+ cancelPainter(): void;
116
+ /** 按目标类型过滤写入;backgroundColor 全类型通用,与格式工具栏口径一致 */
117
+ applyPainter(el: RuntimeElement): boolean;
118
+ /** Vue 版 watch(selectedIds) 的等价入口:shell 在选中集变化后调用;单击模式刷一次即退出 */
119
+ painterSyncSelection(): void;
120
+ /** Esc 退出连续刷:shell 绑定 keydown 后转发(输入控件聚焦时忽略,与 Vue 版一致) */
121
+ handlePainterKeydown(e: KeyboardEvent): void;
122
+ }
@@ -0,0 +1,22 @@
1
+ /*!
2
+ * @worm-vue3-print/common v1.4.0-beta.0
3
+ * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
+ * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ export type AttrValue = string | number | boolean | null | undefined;
8
+ export interface Child {
9
+ node: Node;
10
+ }
11
+ export interface El {
12
+ tag: string;
13
+ props: Record<string, unknown>;
14
+ children: unknown[];
15
+ }
16
+ /** h('div', { class, style, onClick, html, ... }, [...]) */
17
+ export declare function h(tag: string, props?: Record<string, unknown>, children?: unknown[]): El;
18
+ export declare function render(node: El | string | Node, parent: Element | ShadowRoot): Element | Text;
19
+ /** 清空容器(重渲染前调用) */
20
+ export declare function clear(node: Element | ShadowRoot): void;
21
+ export declare function mm(v: number): string;
22
+ export declare const SVG_NS_CONST = "http://www.w3.org/2000/svg";
@@ -0,0 +1,10 @@
1
+ /*!
2
+ * @worm-vue3-print/common v1.4.0-beta.0
3
+ * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
+ * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ /** lucide 图标内部 SVG 片段(viewBox 固定 0 0 24 24,stroke 走 currentColor) */
8
+ export declare const ICONS: Record<string, string>;
9
+ /** 生成图标 SVG 字符串;未知图标名返回空串(调用方按文本兜底)。cls 对应 canvas 里挂在 lucide 组件上的 class */
10
+ export declare function iconSvg(name: string, size?: number, cls?: string): string;
@@ -0,0 +1,163 @@
1
+ /*!
2
+ * @worm-vue3-print/common v1.4.0-beta.0
3
+ * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
+ * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ import type { AlignLine, AlignMode, MultiPageTemplateData, PrintBusinessField, RuntimeElement, TableSelection, TemplateData } from '@worm-vue3-print/core/designer';
8
+ import { createRuntimeElement } from '@worm-vue3-print/core/designer';
9
+ /** 拼版模板只允许单页:增页入口被拦截时的提示文案(与 canvas 同口径) */
10
+ export declare const TILING_SINGLE_PAGE_TIP = "\u5F00\u542F\u62FC\u7248\u540E\u53EA\u80FD\u6709\u4E00\u4E2A\u8BBE\u8BA1\u9875\u9762";
11
+ /** 纸面 mm 落点(与 canvas 的 toPaperPoint 同口径,原点为纸张左上角) */
12
+ export interface PaperPoint {
13
+ x: number;
14
+ y: number;
15
+ }
16
+ export interface DesignerOptions {
17
+ initialTemplate?: TemplateData | MultiPageTemplateData;
18
+ initialElements?: RuntimeElement[];
19
+ initialFields?: PrintBusinessField[];
20
+ }
21
+ /** 把三区模板摊平为统一运行时元素池(补 id、打 zone 标) */
22
+ export declare function toRuntimePool(data: TemplateData): TemplateData;
23
+ /** 单页运行时池序列化回三区模板 JSON(按 zone 拆回,补 id/type) */
24
+ export declare function serializePage(page: TemplateData): TemplateData;
25
+ /**
26
+ * 设计器状态容器。
27
+ * 视图层通过 subscribe 收到「结构性变更」通知;高频拖拽走 livePatch 直改 + 定点重绘,
28
+ * 避免每个 mousemove 都全量重渲染(canvas 侧靠 Vue 细粒度响应式,这里显式区分)。
29
+ */
30
+ export declare class DesignerStore {
31
+ scale: number;
32
+ showRuler: boolean;
33
+ showGrid: boolean;
34
+ snapToGrid: boolean;
35
+ showTableGhostBorder: boolean;
36
+ dirty: boolean;
37
+ pages: TemplateData[];
38
+ activePageIndex: number;
39
+ fields: PrintBusinessField[];
40
+ selectedIds: Set<string>;
41
+ previewIds: Set<string>;
42
+ tableSelection: TableSelection | null;
43
+ /** 正在拖拽的元素 id:对应 canvas BaseElement 的 useDrag isDragging,驱动 `.drag-ghost` + `.drag-preview` */
44
+ draggingIds: Set<string>;
45
+ /** 拖拽吸附生成的临时引导线,仅存在于一次拖拽期间(与 canvas 的 guideLines 同语义) */
46
+ adsorbGuides: AlignLine[];
47
+ /** 拖拽/缩放进行中的实时元素覆盖,不落历史 */
48
+ private live;
49
+ private clipboard;
50
+ private moveSessionActive;
51
+ private moveTimer;
52
+ private dragBefore;
53
+ private undoStack;
54
+ private redoStack;
55
+ private listeners;
56
+ private readonly align;
57
+ private readonly group;
58
+ constructor(opts?: DesignerOptions);
59
+ subscribe(fn: () => void): () => void;
60
+ /** 结构性变更后调用:通知视图重渲染并置 dirty */
61
+ emit(markDirty?: boolean): void;
62
+ get templateData(): TemplateData;
63
+ set templateData(v: TemplateData);
64
+ get elements(): RuntimeElement[];
65
+ get tilingEnabled(): boolean;
66
+ switchPage(i: number): void;
67
+ addPage(): void;
68
+ /** 默认页名跳过已占用的编号(对应 canvas nextDefaultPageName) */
69
+ private nextDefaultPageName;
70
+ duplicatePage(i: number): void;
71
+ deletePage(i: number): void;
72
+ renamePage(i: number, name: string): void;
73
+ movePage(from: number, to: number): void;
74
+ /**
75
+ * 选中集变化的副作用钩子(shell 在初始化时挂上):
76
+ * 对应 canvas `useFormatPainter` 里的 `watch(selectedIds)` —— 格式刷是以「选中集变化」为触发点的,
77
+ * 点击选中、框选、图层面板选中都走这一条路径,不能只在拖拽收尾时同步。
78
+ */
79
+ onSelectionChanged?: () => void;
80
+ private setSelection;
81
+ select(ids: Set<string>): void;
82
+ selectOne(id: string, additive?: boolean): void;
83
+ clearSelection(): void;
84
+ /**
85
+ * 画布/图层「单击选中」:对应 canvas useDesignerState 的 selectElement。
86
+ * · Ctrl/Cmd 点击 = 增删单个成员(canvas 的 select(id, true))
87
+ * · 普通点击 = 整组选中(canvas 的 getGroupedIds),组内成员被点中即选中全组
88
+ */
89
+ selectElement(id: string, multiple?: boolean): void;
90
+ selectAll(): void;
91
+ get selectedElements(): RuntimeElement[];
92
+ get selectedElement(): RuntimeElement | null;
93
+ resetSelection(): void;
94
+ setTableSelection(s: TableSelection | null): void;
95
+ setPreview(ids: Set<string>): void;
96
+ commitPreview(): void;
97
+ addGuide(type: 'vertical' | 'horizontal', positionMm: number): void;
98
+ moveGuide(id: string, positionMm: number): void;
99
+ removeGuide(id: string): void;
100
+ addElement(type: Parameters<typeof createRuntimeElement>[0], options?: Partial<RuntimeElement['options']>, dropPoint?: PaperPoint): RuntimeElement;
101
+ addFieldElement(field: PrintBusinessField, options?: Partial<RuntimeElement['options']>, dropPoint?: PaperPoint): RuntimeElement;
102
+ /**
103
+ * 按落点把新元素放进对应区域(canvas 的 placeAtDropPoint):
104
+ * dropPoint 为纸面 mm;页眉/页脚不允许的类型返回 false(调用方不加入元素)。
105
+ */
106
+ private placeAtDropPoint;
107
+ deleteSelected(): void;
108
+ /** 拖拽/缩放过程中的实时值:只进 live 层,不落历史也不触发全量重渲染 */
109
+ livePatch(id: string, patch: Partial<RuntimeElement['options']>): void;
110
+ /** 交互结束:把 live 层落回元素并记一条历史(与 canvas 的「一次拖拽一条记录」同口径) */
111
+ commitLive(): void;
112
+ /** 拖拽跟手集合(对应 canvas BaseElement:主元素 + 同组元素,不含其它选中项) */
113
+ dragIds(id: string): string[];
114
+ /** 丢弃 live 层(Alt+拖拽:canvas 拖拽期间从不写响应式坐标,副本落在落点、原元素回原位) */
115
+ discardLive(): void;
116
+ /**
117
+ * 拖拽/缩放开始快照(对应 canvas 的 dragStart):dragStop 用它挑出几何变化的元素做归区收尾。
118
+ */
119
+ dragStart(): void;
120
+ /**
121
+ * 拖拽/缩放结束归区(对应 canvas 的 dragStop):按元素中心点重判所在区,
122
+ * 跨区换算坐标并改写 zone、页眉页脚内 clamp;类型不允许跨入则退回内容区并提示。
123
+ */
124
+ dragStop(): void;
125
+ private geoSig;
126
+ updateElement(id: string, patch: Partial<RuntimeElement['options']>, record?: boolean): void;
127
+ updateTemplateData(patch: Partial<TemplateData>): void;
128
+ moveLayer(mode: 'top' | 'bottom' | 'up' | 'down'): void;
129
+ alignSelected(mode: AlignMode): void;
130
+ groupSelected(): void;
131
+ ungroupSelected(): void;
132
+ copy(): void;
133
+ cutSelected(): void;
134
+ paste(offset?: number): void;
135
+ /** Ctrl+D 原地复制(对应 canvas duplicateSelected):复用剪贴板,偏移 10+5 */
136
+ duplicateSelected(): void;
137
+ get hasClipboard(): boolean;
138
+ /**
139
+ * 方向键微移(对应 canvas moveSelected):跳过锁定元素、不做 0 钳制(可移出纸面),
140
+ * 300ms 内的连按算一次历史会话。
141
+ */
142
+ moveSelected(dx: number, dy: number): void;
143
+ /** Alt+拖拽落点插入副本(对应 canvas PrintDesigner.onCloneElement):push + 选中副本 + 一条历史 */
144
+ cloneElement(el: RuntimeElement): void;
145
+ recordHistory(): void;
146
+ get canUndo(): boolean;
147
+ get canRedo(): boolean;
148
+ undo(): void;
149
+ redo(): void;
150
+ /** Ctrl+1 重置缩放至 100%(对应 canvas resetZoom) */
151
+ resetZoom(): void;
152
+ /**
153
+ * 设置缩放百分比。canvas 只在「交互缩放」入口钳到 25%,适应窗口可到 5%,放大不设上限。
154
+ */
155
+ setScale(v: number, minPercent?: number): void;
156
+ getTemplateJson(): string;
157
+ loadTemplate(input: TemplateData | MultiPageTemplateData): void;
158
+ /** 当前纸张尺寸(mm),视图层算坐标要用 */
159
+ get paperSize(): {
160
+ width: number;
161
+ height: number;
162
+ };
163
+ }