@bluechaine/print-designer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +154 -0
- package/README.md +151 -0
- package/README.zh-CN.md +5 -0
- package/dist/plugins/api-image.cjs +2 -0
- package/dist/plugins/api-image.cjs.map +1 -0
- package/dist/plugins/api-image.mjs +28 -0
- package/dist/plugins/api-image.mjs.map +1 -0
- package/dist/plugins/api-pdf.cjs +2 -0
- package/dist/plugins/api-pdf.cjs.map +1 -0
- package/dist/plugins/api-pdf.mjs +35 -0
- package/dist/plugins/api-pdf.mjs.map +1 -0
- package/dist/plugins/view-code-edit.cjs +11 -0
- package/dist/plugins/view-code-edit.cjs.map +1 -0
- package/dist/plugins/view-code-edit.mjs +55 -0
- package/dist/plugins/view-code-edit.mjs.map +1 -0
- package/dist/types/plugins/plugin-api-image/src/index.d.ts +11 -0
- package/dist/types/plugins/plugin-api-pdf/src/index.d.ts +15 -0
- package/dist/types/plugins/plugin-view-code-edit/src/index.d.ts +15 -0
- package/dist/types/src/components/Designer.vue.d.ts +2016 -0
- package/dist/types/src/components/DragBox.vue.d.ts +223 -0
- package/dist/types/src/components/Header.vue.d.ts +96 -0
- package/dist/types/src/components/JsonEditorModal.vue.d.ts +25 -0
- package/dist/types/src/components/Preview.vue.d.ts +27 -0
- package/dist/types/src/components/PrintDataEditorModal.vue.d.ts +86 -0
- package/dist/types/src/components/Ruler.vue.d.ts +16 -0
- package/dist/types/src/components/SvpIcon.vue.d.ts +31 -0
- package/dist/types/src/components/Toolbar.vue.d.ts +116 -0
- package/dist/types/src/components/panels/DraggableElsPanel.vue.d.ts +322 -0
- package/dist/types/src/components/panels/LocationExchangePanel.vue.d.ts +226 -0
- package/dist/types/src/components/panels/MiniMapPanel.vue.d.ts +278 -0
- package/dist/types/src/components/panels/PageHistoryPanel.vue.d.ts +345 -0
- package/dist/types/src/components/panels/PageStructurePanel.vue.d.ts +262 -0
- package/dist/types/src/components/panels/PageTabsPanel.vue.d.ts +267 -0
- package/dist/types/src/components/panels/PaperProperties.vue.d.ts +52 -0
- package/dist/types/src/components/panels/PropertiesPanel.vue.d.ts +225 -0
- package/dist/types/src/composables/useDesigner.d.ts +9 -0
- package/dist/types/src/composables/useDesignerUi.d.ts +2 -0
- package/dist/types/src/composables/useDragBox.d.ts +41 -0
- package/dist/types/src/composables/useRuler.d.ts +10 -0
- package/dist/types/src/constants/default-table-element.d.ts +151 -0
- package/dist/types/src/constants/header-elements.d.ts +3 -0
- package/dist/types/src/constants/icons.d.ts +61 -0
- package/dist/types/src/constants/panel-layout.d.ts +74 -0
- package/dist/types/src/constants.d.ts +37 -0
- package/dist/types/src/core/designer-options.d.ts +34 -0
- package/dist/types/src/core/designer-utils.d.ts +209 -0
- package/dist/types/src/core/hiprint-bridge.d.ts +24 -0
- package/dist/types/src/core/hiprint-paper-list.d.ts +20 -0
- package/dist/types/src/core/history-labels.d.ts +8 -0
- package/dist/types/src/core/history.d.ts +24 -0
- package/dist/types/src/core/json-editor-modal.d.ts +15 -0
- package/dist/types/src/core/plugins.d.ts +17 -0
- package/dist/types/src/core/preview-html.d.ts +2 -0
- package/dist/types/src/core/print-data-editor-modal.d.ts +19 -0
- package/dist/types/src/core/providers.d.ts +5 -0
- package/dist/types/src/core/register-icons.d.ts +1 -0
- package/dist/types/src/core/shortcuts.d.ts +20 -0
- package/dist/types/src/core/storage.d.ts +3 -0
- package/dist/types/src/core/stores.d.ts +77 -0
- package/dist/types/src/core/svp-element-provider.d.ts +8 -0
- package/dist/types/src/core/template-fields.d.ts +28 -0
- package/dist/types/src/core/theme.d.ts +1 -0
- package/dist/types/src/i18n/en-US.d.ts +104 -0
- package/dist/types/src/i18n/index.d.ts +12 -0
- package/dist/types/src/i18n/zh-CN.d.ts +104 -0
- package/dist/types/src/index.d.ts +52 -0
- package/dist/types/src/types.d.ts +229 -0
- package/dist/vue2/index.cjs +10329 -0
- package/dist/vue2/index.cjs.map +1 -0
- package/dist/vue2/index.mjs +10324 -0
- package/dist/vue2/index.mjs.map +1 -0
- package/dist/vue2/index.umd.cjs +10330 -0
- package/dist/vue2/index.umd.cjs.map +1 -0
- package/dist/vue2/style.css +2657 -0
- package/dist/vue3/index.cjs +10062 -0
- package/dist/vue3/index.cjs.map +1 -0
- package/dist/vue3/index.mjs +10057 -0
- package/dist/vue3/index.mjs.map +1 -0
- package/dist/vue3/index.umd.cjs +10063 -0
- package/dist/vue3/index.umd.cjs.map +1 -0
- package/dist/vue3/style.css +2657 -0
- package/package.json +129 -0
package/README.en.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @bluechaine/print-designer
|
|
2
|
+
|
|
3
|
+
A visual print template designer for **Vue 2.7+ / Vue 3** (npm: `@bluechaine/print-designer`), powered by
|
|
4
|
+
[`vue-plugin-hiprint`](https://github.com/CcSimple/vue-plugin-hiprint) and
|
|
5
|
+
inspired by the [sv-print](https://www.ibujian.cn/svp/) UI.
|
|
6
|
+
|
|
7
|
+
> Drag-and-drop designer · 28 toolbar actions · Floating panels · Mini map ·
|
|
8
|
+
> Page structure · History · Properties · Form-based print data · Preview · Plugins
|
|
9
|
+
|
|
10
|
+
[中文文档](./README.md)
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pnpm add @bluechaine/print-designer vue-plugin-hiprint jquery
|
|
16
|
+
# or
|
|
17
|
+
npm i @bluechaine/print-designer vue-plugin-hiprint jquery
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Built with [`vue-demi`](https://github.com/vueuse/vue-demi) and ships **two builds**
|
|
21
|
+
under `dist/vue2` and `dist/vue3`.
|
|
22
|
+
|
|
23
|
+
`vue-plugin-hiprint` requires jQuery on `window` — do not externalise it.
|
|
24
|
+
|
|
25
|
+
## Quick start
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import '@bluechaine/print-designer/style.css'
|
|
33
|
+
import { createApp } from 'vue'
|
|
34
|
+
import App from './App.vue'
|
|
35
|
+
|
|
36
|
+
createApp(App).mount('#app')
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```vue
|
|
40
|
+
<template>
|
|
41
|
+
<Designer
|
|
42
|
+
:template="template"
|
|
43
|
+
:print-data="{ name: 'abcde' }"
|
|
44
|
+
:header-new-ele="true"
|
|
45
|
+
:style-option="styleOption"
|
|
46
|
+
:show-option="{ showHeader: true, showToolbar: true, showFooter: true }"
|
|
47
|
+
@on-designed="onDesigned"
|
|
48
|
+
/>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script setup lang="ts">
|
|
52
|
+
import { Designer, pluginApiPdf, pluginViewCodeEdit } from '@bluechaine/print-designer'
|
|
53
|
+
|
|
54
|
+
const template = { panels: [] }
|
|
55
|
+
const styleOption = {
|
|
56
|
+
miniMap: { show: true, mode: 'left' as const },
|
|
57
|
+
options: { show: true, mode: 'right' as const },
|
|
58
|
+
}
|
|
59
|
+
</script>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Components
|
|
63
|
+
|
|
64
|
+
| Component | Description |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `Designer` | Root component — panels, header, toolbar, preview |
|
|
67
|
+
| `Header` | Top bar: file actions + optional quick-insert element tabs |
|
|
68
|
+
| `Toolbar` | Undo/redo, alignment, z-index, font, lock, copy/paste, zoom, panel toggles |
|
|
69
|
+
| `Preview` | Print preview modal (PDF / image when hiprint APIs are available) |
|
|
70
|
+
| `DragBox` | Reusable draggable / foldable floating panel shell |
|
|
71
|
+
|
|
72
|
+
## Customization
|
|
73
|
+
|
|
74
|
+
### Slots
|
|
75
|
+
|
|
76
|
+
| Slot | Purpose |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `#header` | Replace the entire header |
|
|
79
|
+
| `#toolbar` | Replace the toolbar |
|
|
80
|
+
| `#draggableEls` | Replace the drag-elements panel |
|
|
81
|
+
| `#miniMap` | Replace or omit the mini map (`<template #miniMap />`) |
|
|
82
|
+
| `#pageStructure` | Replace the page structure panel |
|
|
83
|
+
| `#pageHistory` | Replace the history panel |
|
|
84
|
+
| `#properties` | Replace the properties panel |
|
|
85
|
+
| `#other` | Extra content inside the workspace |
|
|
86
|
+
| `#footer` | Footer text (default: `hiprint设计器`) |
|
|
87
|
+
| `#right` (on `Header`) | Header right area, e.g. exit button |
|
|
88
|
+
|
|
89
|
+
### `styleOption` — panel layout & toolbar groups
|
|
90
|
+
|
|
91
|
+
Control panel visibility, docking mode, and toolbar section visibility:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
const styleOption = {
|
|
95
|
+
draggableEls: { show: true, mode: 'left' }, // left | right | top | bottom | fixed | default
|
|
96
|
+
miniMap: { show: true },
|
|
97
|
+
pageStructure: { show: true },
|
|
98
|
+
history: { show: true },
|
|
99
|
+
options: { show: true, mode: 'right' }, // properties panel
|
|
100
|
+
editableTools: { show: true }, // align / flip
|
|
101
|
+
zIndexTools: { show: true },
|
|
102
|
+
fontTools: { show: true },
|
|
103
|
+
zoomTools: { show: true },
|
|
104
|
+
rotateTools: { show: true },
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `showOption` — chrome visibility
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
const showOption = {
|
|
112
|
+
showHeader: true,
|
|
113
|
+
showToolbar: true,
|
|
114
|
+
showFooter: true,
|
|
115
|
+
showPower: true, // when false, footer branding text is hidden
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### `headerEleList` — quick insert from header
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<Designer
|
|
123
|
+
:header-new-ele="true"
|
|
124
|
+
:header-ele-list="[
|
|
125
|
+
{ key: 'text', label: 'Text', tid: 'defaultModule.text', icon: 'lucide:type' },
|
|
126
|
+
{ key: 'table', label: 'Table', tid: 'defaultModule.table', icon: 'lucide:table' },
|
|
127
|
+
]"
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
When `headerNewEle` is true and `headerEleList` is empty, items are derived from `catalogue`.
|
|
132
|
+
|
|
133
|
+
### Print data editor
|
|
134
|
+
|
|
135
|
+
Use **Edit Print Data** in the header to open a form built from bindable fields in the current template:
|
|
136
|
+
|
|
137
|
+
- **Basic information** — text / longText elements with a `field`
|
|
138
|
+
- **Table data** — table columns from `fields`, with add/remove rows
|
|
139
|
+
|
|
140
|
+
### Custom table element
|
|
141
|
+
|
|
142
|
+
The default provider (`SvpElementTypeProvider`) replaces `defaultModule.table` with the project default column layout. Override via `providers` or edit `DEFAULT_TABLE_ELEMENT_TYPE`.
|
|
143
|
+
|
|
144
|
+
## Plugins
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { pluginApiPdf } from '@bluechaine/print-designer/plugins/api-pdf'
|
|
148
|
+
import { pluginApiImage } from '@bluechaine/print-designer/plugins/api-image'
|
|
149
|
+
import { pluginViewCodeEdit } from '@bluechaine/print-designer/plugins/view-code-edit'
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|
package/README.md
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# @bluechaine/print-designer
|
|
2
|
+
|
|
3
|
+
面向 **Vue 2.7+ / Vue 3** 的可视化打印模板设计器(npm:`@bluechaine/print-designer`),基于
|
|
4
|
+
[`vue-plugin-hiprint`](https://github.com/CcSimple/vue-plugin-hiprint),UI 参考 [sv-print](https://www.ibujian.cn/svp/)。
|
|
5
|
+
|
|
6
|
+
> 拖拽设计 · 28 项工具栏 · 浮层面板 · 概览图 · 页面结构 · 历史记录 · 属性面板 · 表单化打印数据 · 预览 · 插件
|
|
7
|
+
|
|
8
|
+
[English](./README.en.md)
|
|
9
|
+
|
|
10
|
+
## 安装
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pnpm add @bluechaine/print-designer vue-plugin-hiprint jquery
|
|
14
|
+
# 或
|
|
15
|
+
npm i @bluechaine/print-designer vue-plugin-hiprint jquery
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
项目使用 [`vue-demi`](https://github.com/vueuse/vue-demi),在 `dist/vue2` 与 `dist/vue3` 下分别提供构建产物。
|
|
19
|
+
|
|
20
|
+
`vue-plugin-hiprint` 依赖全局 `window.jQuery`,请勿将其 external 掉。
|
|
21
|
+
|
|
22
|
+
## 快速开始
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<link rel="stylesheet" type="text/css" media="print" href="/print-lock.css" />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import '@bluechaine/print-designer/style.css'
|
|
30
|
+
import { createApp } from 'vue'
|
|
31
|
+
import App from './App.vue'
|
|
32
|
+
|
|
33
|
+
createApp(App).mount('#app')
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```vue
|
|
37
|
+
<template>
|
|
38
|
+
<Designer
|
|
39
|
+
:template="template"
|
|
40
|
+
:print-data="{ name: 'abcde' }"
|
|
41
|
+
:header-new-ele="true"
|
|
42
|
+
:style-option="styleOption"
|
|
43
|
+
:show-option="{ showHeader: true, showToolbar: true, showFooter: true }"
|
|
44
|
+
@on-designed="onDesigned"
|
|
45
|
+
/>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
|
+
<script setup lang="ts">
|
|
49
|
+
import { Designer, pluginApiPdf, pluginViewCodeEdit } from '@bluechaine/print-designer'
|
|
50
|
+
|
|
51
|
+
const template = { panels: [] }
|
|
52
|
+
const styleOption = {
|
|
53
|
+
miniMap: { show: true, mode: 'left' as const },
|
|
54
|
+
options: { show: true, mode: 'right' as const },
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 组件
|
|
60
|
+
|
|
61
|
+
| 组件 | 说明 |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `Designer` | 根组件,组装面板、顶栏、工具栏、预览 |
|
|
64
|
+
| `Header` | 顶栏:文件操作 + 可选的元素快捷插入 |
|
|
65
|
+
| `Toolbar` | 撤销/重做、对齐、层级、字号、锁定、复制粘贴、缩放、面板开关 |
|
|
66
|
+
| `Preview` | 打印预览弹窗(支持 PDF / 图片导出,取决于 hiprint API) |
|
|
67
|
+
| `DragBox` | 可拖拽、可折叠的浮层面板容器 |
|
|
68
|
+
|
|
69
|
+
## 自定义
|
|
70
|
+
|
|
71
|
+
### 插槽
|
|
72
|
+
|
|
73
|
+
| 插槽 | 用途 |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `#header` | 替换整个顶栏 |
|
|
76
|
+
| `#toolbar` | 替换工具栏 |
|
|
77
|
+
| `#draggableEls` | 替换拖拽元素面板 |
|
|
78
|
+
| `#miniMap` | 替换或隐藏概览图(`<template #miniMap />`) |
|
|
79
|
+
| `#pageStructure` | 替换页面结构面板 |
|
|
80
|
+
| `#pageHistory` | 替换历史记录面板 |
|
|
81
|
+
| `#properties` | 替换属性面板 |
|
|
82
|
+
| `#other` | 工作区内的额外内容 |
|
|
83
|
+
| `#footer` | 底部文案(默认:`hiprint设计器`) |
|
|
84
|
+
| `#right`(`Header` 上) | 顶栏右侧,如退出按钮 |
|
|
85
|
+
|
|
86
|
+
### `styleOption` — 面板布局与工具栏分组
|
|
87
|
+
|
|
88
|
+
控制面板显隐、停靠方式,以及工具栏分组显隐:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const styleOption = {
|
|
92
|
+
draggableEls: { show: true, mode: 'left' }, // left | right | top | bottom | fixed | default
|
|
93
|
+
miniMap: { show: true },
|
|
94
|
+
pageStructure: { show: true },
|
|
95
|
+
history: { show: true },
|
|
96
|
+
options: { show: true, mode: 'right' }, // 属性面板
|
|
97
|
+
editableTools: { show: true }, // 对齐 / 翻转
|
|
98
|
+
zIndexTools: { show: true }, // 层级
|
|
99
|
+
fontTools: { show: true }, // 字号
|
|
100
|
+
zoomTools: { show: true }, // 缩放
|
|
101
|
+
rotateTools: { show: true }, // 旋转
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### `showOption` — 界面区域显隐
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const showOption = {
|
|
109
|
+
showHeader: true,
|
|
110
|
+
showToolbar: true,
|
|
111
|
+
showFooter: true,
|
|
112
|
+
showPower: true, // 为 false 时隐藏底部品牌文案
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `headerEleList` — 顶栏快捷插入元素
|
|
117
|
+
|
|
118
|
+
```vue
|
|
119
|
+
<Designer
|
|
120
|
+
:header-new-ele="true"
|
|
121
|
+
:header-ele-list="[
|
|
122
|
+
{ key: 'text', label: '文本', tid: 'defaultModule.text', icon: 'lucide:type' },
|
|
123
|
+
{ key: 'table', label: '表格', tid: 'defaultModule.table', icon: 'lucide:table' },
|
|
124
|
+
]"
|
|
125
|
+
/>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`headerNewEle` 为 `true` 且未传 `headerEleList` 时,会从 `catalogue` 自动生成列表。
|
|
129
|
+
|
|
130
|
+
### 编辑打印数据
|
|
131
|
+
|
|
132
|
+
点击顶栏 **编辑打印数据**,会从当前模板解析可绑定字段,以表单展示:
|
|
133
|
+
|
|
134
|
+
- **基础信息数据** — 设置了 `field` 的文本 / 长文元素
|
|
135
|
+
- **表格信息数据** — 表格 `fields` 列定义,支持多行增删
|
|
136
|
+
|
|
137
|
+
### 自定义表格元素
|
|
138
|
+
|
|
139
|
+
默认 Provider(`SvpElementTypeProvider`)会替换 `defaultModule.table` 的默认列结构。可通过 `providers` 扩展,或修改 `DEFAULT_TABLE_ELEMENT_TYPE`。
|
|
140
|
+
|
|
141
|
+
## 插件
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
import { pluginApiPdf } from '@bluechaine/print-designer/plugins/api-pdf'
|
|
145
|
+
import { pluginApiImage } from '@bluechaine/print-designer/plugins/api-image'
|
|
146
|
+
import { pluginViewCodeEdit } from '@bluechaine/print-designer/plugins/view-code-edit'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 许可
|
|
150
|
+
|
|
151
|
+
MIT
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=(e={})=>({name:"plugin-api-image",description:"Exports the current template as PNG / JPEG.",config:{type:"png",...e},hooks:[{hook:"beforePrint2",name:"export-image",priority:100,run:async(n,a,r)=>{if(r!=="image")return;const i=(a==null?void 0:a.printData)??{};if(typeof e.convert=="function")return await e.convert(n,i),!1;if(n&&typeof n.toImage=="function"){const o=typeof e.filename=="function"?e.filename(i):e.filename??"image";return n.toImage(i,o,e.type??"png"),!1}console.warn("[plugin-api-image] hiprintTemplate.toImage not available; provide opts.convert")}}]});exports.default=t;exports.pluginApiImage=t;
|
|
2
|
+
//# sourceMappingURL=api-image.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-image.cjs","sources":["../../plugins/plugin-api-image/src/index.ts"],"sourcesContent":["/**\n * Print-to-image plugin. Backs the Preview modal's \"Export image\" button.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface ImagePluginOptions {\n filename?: string | ((data: any) => string)\n type?: 'png' | 'jpeg'\n convert?: (template: any, data: any) => Promise<void> | void\n}\n\nexport const pluginApiImage: PluginFactory<ImagePluginOptions> = (opts = {}) => {\n const plugin: PluginOptions = {\n name: 'plugin-api-image',\n description: 'Exports the current template as PNG / JPEG.',\n config: { type: 'png', ...opts },\n hooks: [\n {\n hook: 'beforePrint2',\n name: 'export-image',\n priority: 100,\n run: async (tpl: any, utils: any, kind: string) => {\n if (kind !== 'image') return\n const data = utils?.printData ?? {}\n if (typeof opts.convert === 'function') {\n await opts.convert(tpl, data)\n return false\n }\n if (tpl && typeof tpl.toImage === 'function') {\n const name = typeof opts.filename === 'function'\n ? opts.filename(data)\n : opts.filename ?? 'image'\n tpl.toImage(data, name, opts.type ?? 'png')\n return false\n }\n console.warn('[plugin-api-image] hiprintTemplate.toImage not available; provide opts.convert')\n return undefined\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginApiImage\n"],"names":["pluginApiImage","opts","tpl","utils","kind","data","name"],"mappings":"4GAWO,MAAMA,EAAoD,CAACC,EAAO,MACzC,CAC5B,KAAM,mBACN,YAAa,8CACb,OAAQ,CAAE,KAAM,MAAO,GAAGA,CAAA,EAC1B,MAAO,CACL,CACE,KAAM,eACN,KAAM,eACN,SAAU,IACV,IAAK,MAAOC,EAAUC,EAAYC,IAAiB,CACjD,GAAIA,IAAS,QAAS,OACtB,MAAMC,GAAOF,GAAA,YAAAA,EAAO,YAAa,CAAA,EACjC,GAAI,OAAOF,EAAK,SAAY,WAC1B,aAAMA,EAAK,QAAQC,EAAKG,CAAI,EACrB,GAET,GAAIH,GAAO,OAAOA,EAAI,SAAY,WAAY,CAC5C,MAAMI,EAAO,OAAOL,EAAK,UAAa,WAClCA,EAAK,SAASI,CAAI,EAClBJ,EAAK,UAAY,QACrB,OAAAC,EAAI,QAAQG,EAAMC,EAAML,EAAK,MAAQ,KAAK,EACnC,EACT,CACA,QAAQ,KAAK,gFAAgF,CAE/F,CAAA,CACF,CACF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const f = (e = {}) => ({
|
|
2
|
+
name: "plugin-api-image",
|
|
3
|
+
description: "Exports the current template as PNG / JPEG.",
|
|
4
|
+
config: { type: "png", ...e },
|
|
5
|
+
hooks: [
|
|
6
|
+
{
|
|
7
|
+
hook: "beforePrint2",
|
|
8
|
+
name: "export-image",
|
|
9
|
+
priority: 100,
|
|
10
|
+
run: async (n, a, t) => {
|
|
11
|
+
if (t !== "image") return;
|
|
12
|
+
const i = (a == null ? void 0 : a.printData) ?? {};
|
|
13
|
+
if (typeof e.convert == "function")
|
|
14
|
+
return await e.convert(n, i), !1;
|
|
15
|
+
if (n && typeof n.toImage == "function") {
|
|
16
|
+
const r = typeof e.filename == "function" ? e.filename(i) : e.filename ?? "image";
|
|
17
|
+
return n.toImage(i, r, e.type ?? "png"), !1;
|
|
18
|
+
}
|
|
19
|
+
console.warn("[plugin-api-image] hiprintTemplate.toImage not available; provide opts.convert");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
});
|
|
24
|
+
export {
|
|
25
|
+
f as default,
|
|
26
|
+
f as pluginApiImage
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=api-image.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-image.mjs","sources":["../../plugins/plugin-api-image/src/index.ts"],"sourcesContent":["/**\n * Print-to-image plugin. Backs the Preview modal's \"Export image\" button.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface ImagePluginOptions {\n filename?: string | ((data: any) => string)\n type?: 'png' | 'jpeg'\n convert?: (template: any, data: any) => Promise<void> | void\n}\n\nexport const pluginApiImage: PluginFactory<ImagePluginOptions> = (opts = {}) => {\n const plugin: PluginOptions = {\n name: 'plugin-api-image',\n description: 'Exports the current template as PNG / JPEG.',\n config: { type: 'png', ...opts },\n hooks: [\n {\n hook: 'beforePrint2',\n name: 'export-image',\n priority: 100,\n run: async (tpl: any, utils: any, kind: string) => {\n if (kind !== 'image') return\n const data = utils?.printData ?? {}\n if (typeof opts.convert === 'function') {\n await opts.convert(tpl, data)\n return false\n }\n if (tpl && typeof tpl.toImage === 'function') {\n const name = typeof opts.filename === 'function'\n ? opts.filename(data)\n : opts.filename ?? 'image'\n tpl.toImage(data, name, opts.type ?? 'png')\n return false\n }\n console.warn('[plugin-api-image] hiprintTemplate.toImage not available; provide opts.convert')\n return undefined\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginApiImage\n"],"names":["pluginApiImage","opts","tpl","utils","kind","data","name"],"mappings":"AAWO,MAAMA,IAAoD,CAACC,IAAO,QACzC;AAAA,EAC5B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,EAAE,MAAM,OAAO,GAAGA,EAAA;AAAA,EAC1B,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,KAAK,OAAOC,GAAUC,GAAYC,MAAiB;AACjD,YAAIA,MAAS,QAAS;AACtB,cAAMC,KAAOF,KAAA,gBAAAA,EAAO,cAAa,CAAA;AACjC,YAAI,OAAOF,EAAK,WAAY;AAC1B,uBAAMA,EAAK,QAAQC,GAAKG,CAAI,GACrB;AAET,YAAIH,KAAO,OAAOA,EAAI,WAAY,YAAY;AAC5C,gBAAMI,IAAO,OAAOL,EAAK,YAAa,aAClCA,EAAK,SAASI,CAAI,IAClBJ,EAAK,YAAY;AACrB,iBAAAC,EAAI,QAAQG,GAAMC,GAAML,EAAK,QAAQ,KAAK,GACnC;AAAA,QACT;AACA,gBAAQ,KAAK,gFAAgF;AAAA,MAE/F;AAAA,IAAA;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const i=(e={})=>({name:"plugin-api-pdf",description:"Exports the current template as a PDF document.",config:{...e},hooks:[{hook:"ready",name:"install-toPdf",priority:100,run:n=>{}},{hook:"beforePrint2",name:"export-pdf",priority:100,run:async(n,t,r)=>{if(r!=="pdf")return;const o=(t==null?void 0:t.printData)??{};if(typeof e.convert=="function")return await e.convert(n,o),!1;if(n&&typeof n.toPdf=="function"){const a=typeof e.filename=="function"?e.filename(o):e.filename??"document";return n.toPdf(o,a),!1}console.warn("[plugin-api-pdf] hiprintTemplate.toPdf not available; provide opts.convert")}}]});exports.default=i;exports.pluginApiPdf=i;
|
|
2
|
+
//# sourceMappingURL=api-pdf.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-pdf.cjs","sources":["../../plugins/plugin-api-pdf/src/index.ts"],"sourcesContent":["/**\n * Print-to-PDF plugin. Wires `hiprintTemplate.toPdf` so the `Preview` modal\n * can offer a \"Export PDF\" button. The user must supply jspdf + html2canvas\n * in their host project (peer dependencies), or override the implementation.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface PdfPluginOptions {\n filename?: string | ((data: any) => string)\n /**\n * Custom converter. If omitted we try `hiprintTemplate.toPdf` then jspdf.\n */\n convert?: (template: any, data: any) => Promise<void> | void\n}\n\nexport const pluginApiPdf: PluginFactory<PdfPluginOptions> = (opts = {}) => {\n const plugin: PluginOptions = {\n name: 'plugin-api-pdf',\n description: 'Exports the current template as a PDF document.',\n config: { ...opts },\n hooks: [\n {\n hook: 'ready',\n name: 'install-toPdf',\n priority: 100,\n run: (_utils: any) => {\n // Hook reserved for future extension.\n },\n },\n {\n hook: 'beforePrint2',\n name: 'export-pdf',\n priority: 100,\n run: async (tpl: any, utils: any, kind: string) => {\n if (kind !== 'pdf') return\n const data = utils?.printData ?? {}\n if (typeof opts.convert === 'function') {\n await opts.convert(tpl, data)\n return false\n }\n if (tpl && typeof tpl.toPdf === 'function') {\n const name = typeof opts.filename === 'function'\n ? opts.filename(data)\n : opts.filename ?? 'document'\n tpl.toPdf(data, name)\n return false\n }\n console.warn('[plugin-api-pdf] hiprintTemplate.toPdf not available; provide opts.convert')\n return undefined\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginApiPdf\n"],"names":["pluginApiPdf","opts","_utils","tpl","utils","kind","data","name"],"mappings":"4GAeO,MAAMA,EAAgD,CAACC,EAAO,MACrC,CAC5B,KAAM,iBACN,YAAa,kDACb,OAAQ,CAAE,GAAGA,CAAA,EACb,MAAO,CACL,CACE,KAAM,QACN,KAAM,gBACN,SAAU,IACV,IAAMC,GAAgB,CAEtB,CAAA,EAEF,CACE,KAAM,eACN,KAAM,aACN,SAAU,IACV,IAAK,MAAOC,EAAUC,EAAYC,IAAiB,CACjD,GAAIA,IAAS,MAAO,OACpB,MAAMC,GAAOF,GAAA,YAAAA,EAAO,YAAa,CAAA,EACjC,GAAI,OAAOH,EAAK,SAAY,WAC1B,aAAMA,EAAK,QAAQE,EAAKG,CAAI,EACrB,GAET,GAAIH,GAAO,OAAOA,EAAI,OAAU,WAAY,CAC1C,MAAMI,EAAO,OAAON,EAAK,UAAa,WAClCA,EAAK,SAASK,CAAI,EAClBL,EAAK,UAAY,WACrB,OAAAE,EAAI,MAAMG,EAAMC,CAAI,EACb,EACT,CACA,QAAQ,KAAK,4EAA4E,CAE3F,CAAA,CACF,CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const f = (n = {}) => ({
|
|
2
|
+
name: "plugin-api-pdf",
|
|
3
|
+
description: "Exports the current template as a PDF document.",
|
|
4
|
+
config: { ...n },
|
|
5
|
+
hooks: [
|
|
6
|
+
{
|
|
7
|
+
hook: "ready",
|
|
8
|
+
name: "install-toPdf",
|
|
9
|
+
priority: 100,
|
|
10
|
+
run: (e) => {
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
hook: "beforePrint2",
|
|
15
|
+
name: "export-pdf",
|
|
16
|
+
priority: 100,
|
|
17
|
+
run: async (e, o, r) => {
|
|
18
|
+
if (r !== "pdf") return;
|
|
19
|
+
const t = (o == null ? void 0 : o.printData) ?? {};
|
|
20
|
+
if (typeof n.convert == "function")
|
|
21
|
+
return await n.convert(e, t), !1;
|
|
22
|
+
if (e && typeof e.toPdf == "function") {
|
|
23
|
+
const a = typeof n.filename == "function" ? n.filename(t) : n.filename ?? "document";
|
|
24
|
+
return e.toPdf(t, a), !1;
|
|
25
|
+
}
|
|
26
|
+
console.warn("[plugin-api-pdf] hiprintTemplate.toPdf not available; provide opts.convert");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
});
|
|
31
|
+
export {
|
|
32
|
+
f as default,
|
|
33
|
+
f as pluginApiPdf
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=api-pdf.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-pdf.mjs","sources":["../../plugins/plugin-api-pdf/src/index.ts"],"sourcesContent":["/**\n * Print-to-PDF plugin. Wires `hiprintTemplate.toPdf` so the `Preview` modal\n * can offer a \"Export PDF\" button. The user must supply jspdf + html2canvas\n * in their host project (peer dependencies), or override the implementation.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface PdfPluginOptions {\n filename?: string | ((data: any) => string)\n /**\n * Custom converter. If omitted we try `hiprintTemplate.toPdf` then jspdf.\n */\n convert?: (template: any, data: any) => Promise<void> | void\n}\n\nexport const pluginApiPdf: PluginFactory<PdfPluginOptions> = (opts = {}) => {\n const plugin: PluginOptions = {\n name: 'plugin-api-pdf',\n description: 'Exports the current template as a PDF document.',\n config: { ...opts },\n hooks: [\n {\n hook: 'ready',\n name: 'install-toPdf',\n priority: 100,\n run: (_utils: any) => {\n // Hook reserved for future extension.\n },\n },\n {\n hook: 'beforePrint2',\n name: 'export-pdf',\n priority: 100,\n run: async (tpl: any, utils: any, kind: string) => {\n if (kind !== 'pdf') return\n const data = utils?.printData ?? {}\n if (typeof opts.convert === 'function') {\n await opts.convert(tpl, data)\n return false\n }\n if (tpl && typeof tpl.toPdf === 'function') {\n const name = typeof opts.filename === 'function'\n ? opts.filename(data)\n : opts.filename ?? 'document'\n tpl.toPdf(data, name)\n return false\n }\n console.warn('[plugin-api-pdf] hiprintTemplate.toPdf not available; provide opts.convert')\n return undefined\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginApiPdf\n"],"names":["pluginApiPdf","opts","_utils","tpl","utils","kind","data","name"],"mappings":"AAeO,MAAMA,IAAgD,CAACC,IAAO,QACrC;AAAA,EAC5B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,QAAQ,EAAE,GAAGA,EAAA;AAAA,EACb,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,KAAK,CAACC,MAAgB;AAAA,MAEtB;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,MACV,KAAK,OAAOC,GAAUC,GAAYC,MAAiB;AACjD,YAAIA,MAAS,MAAO;AACpB,cAAMC,KAAOF,KAAA,gBAAAA,EAAO,cAAa,CAAA;AACjC,YAAI,OAAOH,EAAK,WAAY;AAC1B,uBAAMA,EAAK,QAAQE,GAAKG,CAAI,GACrB;AAET,YAAIH,KAAO,OAAOA,EAAI,SAAU,YAAY;AAC1C,gBAAMI,IAAO,OAAON,EAAK,YAAa,aAClCA,EAAK,SAASK,CAAI,IAClBL,EAAK,YAAY;AACrB,iBAAAE,EAAI,MAAMG,GAAMC,CAAI,GACb;AAAA,QACT;AACA,gBAAQ,KAAK,4EAA4E;AAAA,MAE3F;AAAA,IAAA;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function o(d,l){return new Promise(r=>{if(typeof window>"u")return r(null);const e=document.createElement("div");e.className="svp-modal-mask";const n=document.createElement("div");n.className="svp-modal",n.style.width="min(720px, 90vw)",n.innerHTML=`
|
|
2
|
+
<div class="svp-modal__header">编辑 ${l.name}</div>
|
|
3
|
+
<div class="svp-modal__body" style="padding:0">
|
|
4
|
+
<textarea style="width:100%;height:50vh;border:0;padding:12px;font-family:Menlo,Consolas,monospace;font-size:12px;outline:none"></textarea>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="svp-modal__footer">
|
|
7
|
+
<button class="svp-btn" data-act="cancel">取消</button>
|
|
8
|
+
<button class="svp-btn is-primary" data-act="ok">确定</button>
|
|
9
|
+
</div>
|
|
10
|
+
`;const i=n.querySelector("textarea");i.value=d;function a(t){document.body.removeChild(e),r(t)}n.addEventListener("click",t=>{const s=t.target;s.dataset.act==="cancel"?a(null):s.dataset.act==="ok"&&a(i.value)}),e.addEventListener("click",t=>{t.target===e&&a(null)}),e.appendChild(n),document.body.appendChild(e),i.focus()})}const c=(d={})=>{const l=d.editor??o;return{name:"plugin-view-code-edit",description:"Provides a small in-browser editor for `function` options.",config:{...d},hooks:[{hook:"createPrintElement",name:"editor-create-print-element",priority:100,run:async(e,n,i)=>{var t;if(!e||typeof e!="object"||e.type!=="function"&&e.editor!=="code")return;const a=await l(String(e.value??""),{name:e.name??"function"});a!=null&&(e.value=a,(t=e==null?void 0:e.onChange)==null||t.call(e,a))}}]}};exports.default=c;exports.pluginViewCodeEdit=c;
|
|
11
|
+
//# sourceMappingURL=view-code-edit.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-code-edit.cjs","sources":["../../plugins/plugin-view-code-edit/src/index.ts"],"sourcesContent":["/**\n * Code editor plugin. Pops up a textarea (Monaco is opt-in via `editor`)\n * whenever a property exposes a `function` editor (e.g. `formatter`).\n *\n * Plugin authors can swap the editor by passing a custom `editor` callback\n * that receives the current source and resolves with the next source.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface CodeEditPluginOptions {\n editor?: (source: string, ctx: { name: string }) => Promise<string | null>\n}\n\nfunction defaultEditor(source: string, ctx: { name: string }): Promise<string | null> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') return resolve(null)\n const mask = document.createElement('div')\n mask.className = 'svp-modal-mask'\n const modal = document.createElement('div')\n modal.className = 'svp-modal'\n modal.style.width = 'min(720px, 90vw)'\n modal.innerHTML = `\n <div class=\"svp-modal__header\">编辑 ${ctx.name}</div>\n <div class=\"svp-modal__body\" style=\"padding:0\">\n <textarea style=\"width:100%;height:50vh;border:0;padding:12px;font-family:Menlo,Consolas,monospace;font-size:12px;outline:none\"></textarea>\n </div>\n <div class=\"svp-modal__footer\">\n <button class=\"svp-btn\" data-act=\"cancel\">取消</button>\n <button class=\"svp-btn is-primary\" data-act=\"ok\">确定</button>\n </div>\n `\n const ta = modal.querySelector('textarea') as HTMLTextAreaElement\n ta.value = source\n function close(value: string | null) {\n document.body.removeChild(mask)\n resolve(value)\n }\n modal.addEventListener('click', (e) => {\n const t = e.target as HTMLElement\n if (t.dataset.act === 'cancel') close(null)\n else if (t.dataset.act === 'ok') close(ta.value)\n })\n mask.addEventListener('click', (e) => { if (e.target === mask) close(null) })\n mask.appendChild(modal)\n document.body.appendChild(mask)\n ta.focus()\n })\n}\n\nexport const pluginViewCodeEdit: PluginFactory<CodeEditPluginOptions> = (opts = {}) => {\n const editor = opts.editor ?? defaultEditor\n const plugin: PluginOptions = {\n name: 'plugin-view-code-edit',\n description: 'Provides a small in-browser editor for `function` options.',\n config: { ...opts } as Record<string, unknown>,\n hooks: [\n {\n hook: 'createPrintElement',\n name: 'editor-create-print-element',\n priority: 100,\n run: async (option: any, _printElement: any, _ev: any) => {\n if (!option || typeof option !== 'object') return\n if (option.type !== 'function' && option.editor !== 'code') return\n const next = await editor(String(option.value ?? ''), { name: option.name ?? 'function' })\n if (next == null) return\n option.value = next\n option?.onChange?.(next)\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginViewCodeEdit\n"],"names":["defaultEditor","source","ctx","resolve","mask","modal","ta","close","value","e","t","pluginViewCodeEdit","opts","editor","option","_printElement","_ev","next","_a"],"mappings":"4GAaA,SAASA,EAAcC,EAAgBC,EAA+C,CACpF,OAAO,IAAI,QAASC,GAAY,CAC9B,GAAI,OAAO,OAAW,IAAa,OAAOA,EAAQ,IAAI,EACtD,MAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,UAAY,iBACjB,MAAMC,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,UAAY,YAClBA,EAAM,MAAM,MAAQ,mBACpBA,EAAM,UAAY;AAAA,0CACoBH,EAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAS9C,MAAMI,EAAKD,EAAM,cAAc,UAAU,EACzCC,EAAG,MAAQL,EACX,SAASM,EAAMC,EAAsB,CACnC,SAAS,KAAK,YAAYJ,CAAI,EAC9BD,EAAQK,CAAK,CACf,CACAH,EAAM,iBAAiB,QAAUI,GAAM,CACrC,MAAMC,EAAID,EAAE,OACRC,EAAE,QAAQ,MAAQ,WAAgB,IAAI,EACjCA,EAAE,QAAQ,MAAQ,MAAMH,EAAMD,EAAG,KAAK,CACjD,CAAC,EACDF,EAAK,iBAAiB,QAAUK,GAAM,CAAMA,EAAE,SAAWL,GAAMG,EAAM,IAAI,CAAE,CAAC,EAC5EH,EAAK,YAAYC,CAAK,EACtB,SAAS,KAAK,YAAYD,CAAI,EAC9BE,EAAG,MAAA,CACL,CAAC,CACH,CAEO,MAAMK,EAA2D,CAACC,EAAO,KAAO,CACrF,MAAMC,EAASD,EAAK,QAAUZ,EAqB9B,MApB8B,CAC5B,KAAM,wBACN,YAAa,6DACb,OAAQ,CAAE,GAAGY,CAAA,EACb,MAAO,CACL,CACE,KAAM,qBACN,KAAM,8BACN,SAAU,IACV,IAAK,MAAOE,EAAaC,EAAoBC,IAAa,OAExD,GADI,CAACF,GAAU,OAAOA,GAAW,UAC7BA,EAAO,OAAS,YAAcA,EAAO,SAAW,OAAQ,OAC5D,MAAMG,EAAO,MAAMJ,EAAO,OAAOC,EAAO,OAAS,EAAE,EAAG,CAAE,KAAMA,EAAO,MAAQ,WAAY,EACrFG,GAAQ,OACZH,EAAO,MAAQG,GACfC,EAAAJ,GAAA,YAAAA,EAAQ,WAAR,MAAAI,EAAA,KAAAJ,EAAmBG,GACrB,CAAA,CACF,CACF,CAGJ"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
function c(d, l) {
|
|
2
|
+
return new Promise((s) => {
|
|
3
|
+
if (typeof window > "u") return s(null);
|
|
4
|
+
const e = document.createElement("div");
|
|
5
|
+
e.className = "svp-modal-mask";
|
|
6
|
+
const n = document.createElement("div");
|
|
7
|
+
n.className = "svp-modal", n.style.width = "min(720px, 90vw)", n.innerHTML = `
|
|
8
|
+
<div class="svp-modal__header">编辑 ${l.name}</div>
|
|
9
|
+
<div class="svp-modal__body" style="padding:0">
|
|
10
|
+
<textarea style="width:100%;height:50vh;border:0;padding:12px;font-family:Menlo,Consolas,monospace;font-size:12px;outline:none"></textarea>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="svp-modal__footer">
|
|
13
|
+
<button class="svp-btn" data-act="cancel">取消</button>
|
|
14
|
+
<button class="svp-btn is-primary" data-act="ok">确定</button>
|
|
15
|
+
</div>
|
|
16
|
+
`;
|
|
17
|
+
const i = n.querySelector("textarea");
|
|
18
|
+
i.value = d;
|
|
19
|
+
function a(t) {
|
|
20
|
+
document.body.removeChild(e), s(t);
|
|
21
|
+
}
|
|
22
|
+
n.addEventListener("click", (t) => {
|
|
23
|
+
const r = t.target;
|
|
24
|
+
r.dataset.act === "cancel" ? a(null) : r.dataset.act === "ok" && a(i.value);
|
|
25
|
+
}), e.addEventListener("click", (t) => {
|
|
26
|
+
t.target === e && a(null);
|
|
27
|
+
}), e.appendChild(n), document.body.appendChild(e), i.focus();
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const o = (d = {}) => {
|
|
31
|
+
const l = d.editor ?? c;
|
|
32
|
+
return {
|
|
33
|
+
name: "plugin-view-code-edit",
|
|
34
|
+
description: "Provides a small in-browser editor for `function` options.",
|
|
35
|
+
config: { ...d },
|
|
36
|
+
hooks: [
|
|
37
|
+
{
|
|
38
|
+
hook: "createPrintElement",
|
|
39
|
+
name: "editor-create-print-element",
|
|
40
|
+
priority: 100,
|
|
41
|
+
run: async (e, n, i) => {
|
|
42
|
+
var t;
|
|
43
|
+
if (!e || typeof e != "object" || e.type !== "function" && e.editor !== "code") return;
|
|
44
|
+
const a = await l(String(e.value ?? ""), { name: e.name ?? "function" });
|
|
45
|
+
a != null && (e.value = a, (t = e == null ? void 0 : e.onChange) == null || t.call(e, a));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
o as default,
|
|
53
|
+
o as pluginViewCodeEdit
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=view-code-edit.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-code-edit.mjs","sources":["../../plugins/plugin-view-code-edit/src/index.ts"],"sourcesContent":["/**\n * Code editor plugin. Pops up a textarea (Monaco is opt-in via `editor`)\n * whenever a property exposes a `function` editor (e.g. `formatter`).\n *\n * Plugin authors can swap the editor by passing a custom `editor` callback\n * that receives the current source and resolves with the next source.\n */\nimport type { PluginFactory, PluginOptions } from '../../../src/types'\n\nexport interface CodeEditPluginOptions {\n editor?: (source: string, ctx: { name: string }) => Promise<string | null>\n}\n\nfunction defaultEditor(source: string, ctx: { name: string }): Promise<string | null> {\n return new Promise((resolve) => {\n if (typeof window === 'undefined') return resolve(null)\n const mask = document.createElement('div')\n mask.className = 'svp-modal-mask'\n const modal = document.createElement('div')\n modal.className = 'svp-modal'\n modal.style.width = 'min(720px, 90vw)'\n modal.innerHTML = `\n <div class=\"svp-modal__header\">编辑 ${ctx.name}</div>\n <div class=\"svp-modal__body\" style=\"padding:0\">\n <textarea style=\"width:100%;height:50vh;border:0;padding:12px;font-family:Menlo,Consolas,monospace;font-size:12px;outline:none\"></textarea>\n </div>\n <div class=\"svp-modal__footer\">\n <button class=\"svp-btn\" data-act=\"cancel\">取消</button>\n <button class=\"svp-btn is-primary\" data-act=\"ok\">确定</button>\n </div>\n `\n const ta = modal.querySelector('textarea') as HTMLTextAreaElement\n ta.value = source\n function close(value: string | null) {\n document.body.removeChild(mask)\n resolve(value)\n }\n modal.addEventListener('click', (e) => {\n const t = e.target as HTMLElement\n if (t.dataset.act === 'cancel') close(null)\n else if (t.dataset.act === 'ok') close(ta.value)\n })\n mask.addEventListener('click', (e) => { if (e.target === mask) close(null) })\n mask.appendChild(modal)\n document.body.appendChild(mask)\n ta.focus()\n })\n}\n\nexport const pluginViewCodeEdit: PluginFactory<CodeEditPluginOptions> = (opts = {}) => {\n const editor = opts.editor ?? defaultEditor\n const plugin: PluginOptions = {\n name: 'plugin-view-code-edit',\n description: 'Provides a small in-browser editor for `function` options.',\n config: { ...opts } as Record<string, unknown>,\n hooks: [\n {\n hook: 'createPrintElement',\n name: 'editor-create-print-element',\n priority: 100,\n run: async (option: any, _printElement: any, _ev: any) => {\n if (!option || typeof option !== 'object') return\n if (option.type !== 'function' && option.editor !== 'code') return\n const next = await editor(String(option.value ?? ''), { name: option.name ?? 'function' })\n if (next == null) return\n option.value = next\n option?.onChange?.(next)\n },\n },\n ],\n }\n return plugin\n}\n\nexport default pluginViewCodeEdit\n"],"names":["defaultEditor","source","ctx","resolve","mask","modal","ta","close","value","e","t","pluginViewCodeEdit","opts","editor","option","_printElement","_ev","_a","next"],"mappings":"AAaA,SAASA,EAAcC,GAAgBC,GAA+C;AACpF,SAAO,IAAI,QAAQ,CAACC,MAAY;AAC9B,QAAI,OAAO,SAAW,IAAa,QAAOA,EAAQ,IAAI;AACtD,UAAMC,IAAO,SAAS,cAAc,KAAK;AACzC,IAAAA,EAAK,YAAY;AACjB,UAAMC,IAAQ,SAAS,cAAc,KAAK;AAC1C,IAAAA,EAAM,YAAY,aAClBA,EAAM,MAAM,QAAQ,oBACpBA,EAAM,YAAY;AAAA,0CACoBH,EAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS9C,UAAMI,IAAKD,EAAM,cAAc,UAAU;AACzC,IAAAC,EAAG,QAAQL;AACX,aAASM,EAAMC,GAAsB;AACnC,eAAS,KAAK,YAAYJ,CAAI,GAC9BD,EAAQK,CAAK;AAAA,IACf;AACA,IAAAH,EAAM,iBAAiB,SAAS,CAACI,MAAM;AACrC,YAAMC,IAAID,EAAE;AACZ,MAAIC,EAAE,QAAQ,QAAQ,aAAgB,IAAI,IACjCA,EAAE,QAAQ,QAAQ,QAAMH,EAAMD,EAAG,KAAK;AAAA,IACjD,CAAC,GACDF,EAAK,iBAAiB,SAAS,CAACK,MAAM;AAAE,MAAIA,EAAE,WAAWL,KAAMG,EAAM,IAAI;AAAA,IAAE,CAAC,GAC5EH,EAAK,YAAYC,CAAK,GACtB,SAAS,KAAK,YAAYD,CAAI,GAC9BE,EAAG,MAAA;AAAA,EACL,CAAC;AACH;AAEO,MAAMK,IAA2D,CAACC,IAAO,OAAO;AACrF,QAAMC,IAASD,EAAK,UAAUZ;AAqB9B,SApB8B;AAAA,IAC5B,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,GAAGY,EAAA;AAAA,IACb,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,QACV,KAAK,OAAOE,GAAaC,GAAoBC,MAAa;AA/ClE,cAAAC;AAiDU,cADI,CAACH,KAAU,OAAOA,KAAW,YAC7BA,EAAO,SAAS,cAAcA,EAAO,WAAW,OAAQ;AAC5D,gBAAMI,IAAO,MAAML,EAAO,OAAOC,EAAO,SAAS,EAAE,GAAG,EAAE,MAAMA,EAAO,QAAQ,YAAY;AACzF,UAAII,KAAQ,SACZJ,EAAO,QAAQI,IACfD,IAAAH,KAAA,gBAAAA,EAAQ,aAAR,QAAAG,EAAA,KAAAH,GAAmBI;AAAA,QACrB;AAAA,MAAA;AAAA,IACF;AAAA,EACF;AAGJ;"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print-to-image plugin. Backs the Preview modal's "Export image" button.
|
|
3
|
+
*/
|
|
4
|
+
import type { PluginFactory } from '../../../src/types';
|
|
5
|
+
export interface ImagePluginOptions {
|
|
6
|
+
filename?: string | ((data: any) => string);
|
|
7
|
+
type?: 'png' | 'jpeg';
|
|
8
|
+
convert?: (template: any, data: any) => Promise<void> | void;
|
|
9
|
+
}
|
|
10
|
+
export declare const pluginApiImage: PluginFactory<ImagePluginOptions>;
|
|
11
|
+
export default pluginApiImage;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Print-to-PDF plugin. Wires `hiprintTemplate.toPdf` so the `Preview` modal
|
|
3
|
+
* can offer a "Export PDF" button. The user must supply jspdf + html2canvas
|
|
4
|
+
* in their host project (peer dependencies), or override the implementation.
|
|
5
|
+
*/
|
|
6
|
+
import type { PluginFactory } from '../../../src/types';
|
|
7
|
+
export interface PdfPluginOptions {
|
|
8
|
+
filename?: string | ((data: any) => string);
|
|
9
|
+
/**
|
|
10
|
+
* Custom converter. If omitted we try `hiprintTemplate.toPdf` then jspdf.
|
|
11
|
+
*/
|
|
12
|
+
convert?: (template: any, data: any) => Promise<void> | void;
|
|
13
|
+
}
|
|
14
|
+
export declare const pluginApiPdf: PluginFactory<PdfPluginOptions>;
|
|
15
|
+
export default pluginApiPdf;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code editor plugin. Pops up a textarea (Monaco is opt-in via `editor`)
|
|
3
|
+
* whenever a property exposes a `function` editor (e.g. `formatter`).
|
|
4
|
+
*
|
|
5
|
+
* Plugin authors can swap the editor by passing a custom `editor` callback
|
|
6
|
+
* that receives the current source and resolves with the next source.
|
|
7
|
+
*/
|
|
8
|
+
import type { PluginFactory } from '../../../src/types';
|
|
9
|
+
export interface CodeEditPluginOptions {
|
|
10
|
+
editor?: (source: string, ctx: {
|
|
11
|
+
name: string;
|
|
12
|
+
}) => Promise<string | null>;
|
|
13
|
+
}
|
|
14
|
+
export declare const pluginViewCodeEdit: PluginFactory<CodeEditPluginOptions>;
|
|
15
|
+
export default pluginViewCodeEdit;
|