x-print-designer 0.0.5 → 0.0.7

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.md CHANGED
@@ -15,7 +15,7 @@
15
15
  - [自动保存配置](#自动保存配置)
16
16
  - [模板数据结构(完整格式)](#模板数据结构完整格式)
17
17
  - [元素数据绑定](#元素数据绑定)
18
- - [变量语法参考](#变量语法参考)
18
+ - [图片元素使用说明](#图片元素使用说明)
19
19
  - [支持的元素类型](#支持的元素类型)
20
20
  - [技术栈](#技术栈)
21
21
 
@@ -25,35 +25,112 @@
25
25
 
26
26
  设计器支持两种工作模式,通过 `mode` 属性/方法进行切换。
27
27
 
28
+ ### 概念说明
29
+
30
+ | 概念 | 说明 |
31
+ |------|------|
32
+ | **模板 (Template)** | 页面布局设计,包含元素位置、样式、画布大小等,不包含具体数据 |
33
+ | **数据 (Data)** | 业务数据,如订单信息、报告内容、用户信息等 |
34
+ | **模板 ID** | 模板的唯一标识,用于关联和加载模板 |
35
+ | **数据 ID** | 业务数据的唯一标识,如订单 ID、报告 ID |
36
+
28
37
  ### 模板模式(`template`)— 默认模式
29
38
 
30
- **适用场景:** 创建可复用的打印模板,模板与数据分离。布局固定,数据在打印时动态注入。
39
+ **设计理念:** 模板与数据分离,一个模板可绑定多个不同的数据。
40
+
41
+ **适用场景:**
42
+ - 订单打印(同一订单模板,打印不同订单)
43
+ - 标签打印(同一标签模板,打印不同商品)
44
+ - 快递单据(同一单据模板,打印不同收件人)
31
45
 
46
+ **数据流向:**
47
+ ```
48
+ 模板(保存布局) + 数据(打印时注入) = 最终打印结果
49
+ ```
50
+
51
+ **保存行为:**
32
52
  - 保存时**只保存页面布局**(元素位置、样式、画布大小等)
33
- - **不保存** `testData`(测试数据)
53
+ - **不保存** `testData`
34
54
 
35
55
  ### 报告模式(`report`)
36
56
 
37
- **适用场景:** 数据与布局绑定在一起的完整报告(如检测报告、统计报表)。
57
+ **设计理念:** 数据与布局绑定,保存的是完整的报告快照。
38
58
 
39
- - 保存时**同时保存页面布局 + 测试数据**(`testData`)
59
+ **适用场景:**
60
+ - 检测报告(每次检测结果 + 固定格式的报告模板)
61
+ - 数据报表(当前统计数据的可视化呈现)
62
+ - 档案文件(包含具体数据的完整文档)
40
63
 
41
- ### 对比
64
+ **数据流向:**
65
+ ```
66
+ 报告(模板 + 数据 一起保存) = 完整的报告文件
67
+ ```
68
+
69
+ **保存行为:**
70
+ - 保存时**同时保存页面布局 + 测试数据**
71
+ - `testData` 会被完整保存到模板数据中
42
72
 
43
- | 特性 | `template` | `report` |
44
- |------|-----------|----------|
73
+ ### 两种模式对比
74
+
75
+ | 特性 | `template` 模板模式 | `report` 报告模式 |
76
+ |------|-------------------|------------------|
45
77
  | 保存布局 | ✅ | ✅ |
46
78
  | 保存 testData | ❌ | ✅ |
47
- | 典型用途 | 订单打印、标签 | 检测报告、报表 |
79
+ | 数据与模板关系 | 分离,运行时注入 | 绑定,一起保存 |
80
+ | 模板复用性 | 高,可用于多个数据 | 低,针对当前数据 |
81
+ | 典型用途 | 订单打印、标签 | 检测报告、数据报表 |
82
+ | 数据持久化 | 数据需单独存储 | 数据与模板一起存储 |
83
+
84
+ ### 使用示例
85
+
86
+ **模板模式(推荐用于可复用模板):**
87
+ ```javascript
88
+ // 1. 创建/编辑模板
89
+ const sampleData = {
90
+ id: null, // 无需数据 ID,只是用于预览
91
+ title: "@orderNo", // 绑定变量
92
+ customerName: "@customerName"
93
+ };
94
+
95
+ // 2. 保存模板(只保存布局)
96
+ // payload.data 不包含 testData
97
+
98
+ // 3. 打印时动态注入数据
99
+ designer.setVariables({
100
+ orderNo: "ORD-2024-001",
101
+ customerName: "张三"
102
+ });
103
+ designer.print();
104
+ ```
105
+
106
+ **报告模式(推荐用于完整报告):**
107
+ ```javascript
108
+ // 1. 创建/编辑报告
109
+ const sampleData = {
110
+ id: 8, // 报告 ID
111
+ title: "2024年第一季度销售报告",
112
+ totalAmount: 50000,
113
+ items: [...] // 报告数据
114
+ };
115
+
116
+ // 2. 保存报告(布局 + 数据一起保存)
117
+ // payload.data 包含完整的 testData
118
+
119
+ // 3. 加载后直接打印,无需再次注入数据
120
+ designer.loadTemplate(8);
121
+ designer.print();
122
+ ```
48
123
 
49
124
  ### 切换模式
50
125
 
51
126
  ```vue
52
- <PrintDesigner mode="template" />
53
- <PrintDesigner mode="report" />
127
+ <!-- Vue 组件 -->
128
+ <PrintDesigner mode="template" /> <!-- 模板模式(默认) -->
129
+ <PrintDesigner mode="report" /> <!-- 报告模式 -->
54
130
  ```
55
131
 
56
- ```js
132
+ ```javascript
133
+ // Web Component
57
134
  designer.setMode('template');
58
135
  designer.setMode('report');
59
136
  ```
@@ -206,32 +283,84 @@ await designer.print({ mode: 'browser', options: { silent: true } });
206
283
 
207
284
  ## 传入数据格式
208
285
 
209
- 数据以 **扁平键值对** 形式传入,所有字段在根级别,在模板中通过 `@变量名` 或 `{#变量名}` 直接引用。
286
+ ### 基本要求
210
287
 
211
- ### `sample-data` 字段说明
288
+ `sample-data` 接收一个普通的 JSON 对象,**唯一必填字段是 `id`**,用于标识业务数据的唯一性。其他字段完全自由,可以根据业务需求灵活组织数据结构。
212
289
 
213
290
  | 字段 | 类型 | 必填 | 说明 |
214
291
  |------|------|------|------|
215
- | `id` | `number` / `string` | 是 | **业务数据的 ID**,如报告 ID、订单 ID |
292
+ | `id` | `number` / `string` | 是 | **业务数据的唯一标识**,如报告 ID、订单 ID |
216
293
  | `templateId` | `string` | 否 | 加载的打印模板 ID,不传则用当前已选模板 |
217
294
  | `name` | `string` | 否 | 数据名称,如报告标题、订单名称 |
218
- | `variables` | `object` | 否 | **业务变量对象**,包含模板中绑定的所有字段 |
219
- | 任意自定义字段 | `any` | 否 | 如 `createTime`、`selected`,也可在模板中引用 |
295
+ | `variables` | `object` | 否 | 业务变量对象(可选,用作组织数据的约定) |
296
+ | 任意自定义字段 | `any` | 否 | 如 `createTime`、`customerName`,也可在模板中直接引用 |
297
+
298
+ ### 两种数据传入方式
299
+
300
+ 组件支持两种数据组织方式,**可以任选其一**,组件会自动兼容处理:
301
+
302
+ #### 方式一:带 `variables` 包装(推荐)
303
+
304
+ 将所有业务变量放在 `variables` 对象中,结构清晰,适合复杂业务场景:
305
+
306
+ ```json
307
+ {
308
+ "id": 8,
309
+ "name": "测试报告",
310
+ "templateId": "tpl_report",
311
+ "variables": {
312
+ "title": "报告标题",
313
+ "customerName": "张三",
314
+ "items": [
315
+ { "name": "产品A", "price": 100, "quantity": 2 }
316
+ ],
317
+ "chartData": [
318
+ { "category": "一月", "value": 1200 },
319
+ { "category": "二月", "value": 1500 }
320
+ ]
321
+ }
322
+ }
323
+ ```
324
+
325
+ 模板绑定写法:`@title`、`@customerName`、`@items`、`@chartData`
326
+
327
+ #### 方式二:直接扁平数据(简洁)
328
+
329
+ 将所有字段直接放在根级别,无需 `variables` 包装,适合简单场景:
330
+
331
+ ```json
332
+ {
333
+ "id": 8,
334
+ "name": "测试报告",
335
+ "title": "报告标题",
336
+ "customerName": "张三",
337
+ "items": [
338
+ { "name": "产品A", "price": 100, "quantity": 2 }
339
+ ],
340
+ "chartData": [
341
+ { "category": "一月", "value": 1200 },
342
+ { "category": "二月", "value": 1500 }
343
+ ]
344
+ }
345
+ ```
346
+
347
+ 模板绑定写法:`@title`、`@customerName`、`@items`、`@chartData`
220
348
 
221
- > `id` 是业务数据的标识,`templateId` 是打印模板的标识,两者是不同概念。
349
+ > 两种方式完全等效,组件内部会自动解析变量路径,无需担心格式不匹配。
222
350
 
223
- ### `variables` 内部结构
351
+ ### 支持的数据类型
224
352
 
225
- `variables` 是一个扁平或嵌套的 JSON 对象,其中的所有字段都可在模板元素中通过变量语法绑定。
353
+ 所有字段都可在模板元素中通过变量语法绑定,支持:
226
354
 
227
- 支持的数据类型:
228
- - **字符串** `string` — 文本元素绑定
229
- - **数字** `number` 文本、图表数据
230
- - **布尔值** `boolean`
231
- - **数组** `array` 表格数据源、图表数据源
232
- - **嵌套对象** `object` 多级路径访问
355
+ | 类型 | 示例 | 在模板中绑定 |
356
+ |------|------|-------------|
357
+ | 字符串 | `"张三"` | `@customerName` |
358
+ | 数字 | `100` | `@totalAmount` |
359
+ | 布尔值 | `true` | `@isPaid` |
360
+ | 数组 | `[{...}, {...}]` | `@items` |
361
+ | 嵌套对象 | `{user: {name: "李四"}}` | `@user.name` |
233
362
 
234
- ### 示例:完整数据格式
363
+ ### 完整示例数据格式
235
364
 
236
365
  ```json
237
366
  {
@@ -289,15 +418,16 @@ await designer.print({ mode: 'browser', options: { silent: true } });
289
418
 
290
419
  ### 在模板中绑定变量
291
420
 
292
- | 变量 | 绑定写法 | 应用元素 |
293
- |------|---------|---------|
294
- | `variables.dockname` | `@dockname` 或 `{#dockname}` | 文本 |
295
- | `variables.reportname` | `@reportname` | 文本 |
296
- | `variables.totaldistance` | `@totaldistance` | 文本 |
297
- | `variables.createtime` | `@createtime` | 文本 |
298
- | `variables.flightRecords` | `@flightRecords` | 表格、自定义表格 |
299
- | `variables.taskRecords` | `@taskRecords` | 表格 |
300
- | `variables.chartData` | `@chartData` | 图表 |
421
+ 变量绑定使用 `@变量名` `{#变量名}` 语法。绑定时只需使用变量名,无需关心数据是否在 `variables` 包装下:
422
+
423
+ | 变量路径 | 绑定写法 | 应用元素 |
424
+ |---------|---------|---------|
425
+ | `variables.dockname` / `dockname` | `@dockname` | 文本 |
426
+ | `variables.reportname` / `reportname` | `@reportname` | 文本 |
427
+ | `variables.flightRecords` / `flightRecords` | `@flightRecords` | 表格、自定义表格 |
428
+ | `variables.chartData` / `chartData` | `@chartData` | 图表 |
429
+
430
+ > 组件会自动解析变量路径,无论数据在 `variables.xxx` 还是直接在根级别,都能正确绑定。
301
431
 
302
432
  ### 表格数据
303
433
 
@@ -343,6 +473,34 @@ await designer.print({ mode: 'browser', options: { silent: true } });
343
473
  - **chartYField:** `value`(Y 轴字段名)
344
474
  - **chartNameField:** `category`(饼图名称字段)
345
475
 
476
+ ### 使用注意事项
477
+
478
+ 1. **`id` 字段的重要性**
479
+ - `id` 是业务数据的唯一标识,用于在保存回调中识别当前编辑的数据
480
+ - 如果不传 `id`,保存时 `payload.id` 将为 `null`,表示新建数据
481
+
482
+ 2. **`id` 与 `templateId` 的区别**
483
+ - `id`:业务数据(如订单、报告)的标识
484
+ - `templateId`:打印模板的标识,两者是完全不同的概念
485
+
486
+ 3. **变量命名建议**
487
+ - 使用有意义的变量名,如 `customerName` 而非 `c`
488
+ - 避免使用特殊字符和空格
489
+ - 嵌套路径使用点号分隔,如 `@user.profile.name`
490
+
491
+ 4. **数组数据的注意事项**
492
+ - 表格和图表需要数组类型的数据
493
+ - 数组元素应包含一致的字段结构
494
+ - 示例:`items: [{name: "A", price: 100}, {name: "B", price: 200}]`
495
+
496
+ 5. **动态更新数据**
497
+ - 可以通过 Web Component 的 `setSampleData()` 方法动态更新数据
498
+ - 数据更新后,模板中的变量绑定会自动重新解析
499
+
500
+ 6. **数据验证建议**
501
+ - 确保传入的数据字段与模板中绑定的变量名一致
502
+ - 如果变量找不到对应的数据,模板中会显示为空
503
+
346
504
  ---
347
505
 
348
506
  ## 保存回调 `onSave`
@@ -355,27 +513,99 @@ await designer.print({ mode: 'browser', options: { silent: true } });
355
513
  interface SavePayload {
356
514
  id: string | null; // 模板 ID,null 表示新建
357
515
  name: string; // 模板名称
358
- data: Record<string, any>; // 完整模板数据(pages/canvasSize/watermark/testData...)
516
+ data: Record<string, any>; // 模板数据(见下方详细说明)
359
517
  isNew: boolean; // 是否新建模板
360
518
  }
361
519
  ```
362
520
 
521
+ ### 不同模式下的保存数据差异
522
+
523
+ | 数据字段 | 模板模式 | 报告模式 | 说明 |
524
+ |---------|---------|---------|------|
525
+ | `pages` | ✅ | ✅ | 页面元素布局 |
526
+ | `canvasSize` | ✅ | ✅ | 画布尺寸 |
527
+ | `watermark` | ✅ | ✅ | 水印设置 |
528
+ | `guides` | ✅ | ✅ | 辅助线 |
529
+ | `testData` | ❌ | ✅ | 传入的示例数据 |
530
+ | `unit` | ✅ | ✅ | 单位设置 |
531
+ | `showGrid` | ✅ | ✅ | 网格显示 |
532
+ | ... | ... | ... | 其他配置 |
533
+
534
+ ### 保存数据示例
535
+
536
+ **模板模式保存的数据:**
537
+ ```javascript
538
+ {
539
+ id: "tpl_001", // 模板 ID
540
+ name: "订单打印模板",
541
+ data: {
542
+ pages: [...], // 页面布局
543
+ canvasSize: {...}, // 画布尺寸
544
+ watermark: {...}, // 水印设置
545
+ unit: "mm",
546
+ showGrid: true,
547
+ // ❌ 没有 testData 字段
548
+ },
549
+ isNew: false
550
+ }
551
+ ```
552
+
553
+ **报告模式保存的数据:**
554
+ ```javascript
555
+ {
556
+ id: "rpt_001", // 报告 ID
557
+ name: "第一季度销售报告",
558
+ data: {
559
+ pages: [...], // 页面布局
560
+ canvasSize: {...}, // 画布尺寸
561
+ watermark: {...}, // 水印设置
562
+ unit: "mm",
563
+ showGrid: true,
564
+ // ✅ 包含完整的 testData
565
+ testData: {
566
+ id: 8,
567
+ name: "第一季度销售报告",
568
+ totalAmount: 50000,
569
+ items: [
570
+ { name: "产品A", price: 100, quantity: 200 },
571
+ { name: "产品B", price: 200, quantity: 150 }
572
+ ],
573
+ chartData: [
574
+ { category: "一月", value: 1200 },
575
+ { category: "二月", value: 1500 },
576
+ { category: "三月", value: 1800 }
577
+ ]
578
+ }
579
+ },
580
+ isNew: false
581
+ }
582
+ ```
583
+
363
584
  ### 使用示例
364
585
 
365
586
  ```vue
366
587
  <PrintDesigner
588
+ :mode="mode"
367
589
  :on-save="handleSave"
368
590
  />
369
591
 
370
592
  <script setup>
593
+ import { ref } from 'vue';
594
+
595
+ const mode = ref('template'); // 或 'report'
596
+
371
597
  const handleSave = async (payload) => {
372
- // payload.data 包含 pages、canvasSize、watermark、testData 等所有画布数据
373
- const response = await fetch('/api/save', {
374
- method: 'POST',
375
- headers: { 'Content-Type': 'application/json' },
376
- body: JSON.stringify(payload)
377
- });
378
- if (!response.ok) throw new Error('保存失败');
598
+ console.log('保存模式:', mode.value);
599
+ console.log('保存的数据:', payload);
600
+
601
+ // 根据模式决定如何处理
602
+ if (mode.value === 'template') {
603
+ // 模板模式:保存布局,数据单独处理
604
+ await saveTemplate(payload.id, payload.name, payload.data);
605
+ } else {
606
+ // 报告模式:布局和数据一起保存
607
+ await saveReport(payload.id, payload.name, payload.data);
608
+ }
379
609
  };
380
610
  </script>
381
611
  ```
@@ -578,6 +808,61 @@ interface PrintElement {
578
808
 
579
809
  ---
580
810
 
811
+ ## 图片元素使用说明
812
+
813
+ 图片元素支持 **三种方式** 设置图片:
814
+
815
+ ### 方式 1:直接输入图片 URL
816
+
817
+ 在图片元素的属性面板中,直接在"图片地址"输入框填写图片 URL(支持 HTTP/HTTPS 链接)。
818
+
819
+ ```
820
+ https://example.com/logo.png
821
+ ```
822
+
823
+ ### 方式 2:本地上传(自动转 Base64)
824
+
825
+ 点击属性面板中的 **"上传图片"** 按钮,从本地选择一张图片文件:
826
+
827
+ - 自动将图片转换为 **Base64** 字符串并填入图片地址
828
+ - 限制最大 **2MB**,超出会提示错误
829
+ - 支持所有常见图片格式(PNG、JPG、GIF、WebP 等)
830
+
831
+ > 也可以**双击画布上的图片元素**来快速触发上传(编辑模式下)。
832
+
833
+ ### 方式 3:绑定变量
834
+
835
+ 将图片元素的 `variable` 属性绑定到一个变量名,图片地址从数据中动态读取。
836
+
837
+ | 绑定方式 | 示例 | 数据值要求 |
838
+ |---------|------|-----------|
839
+ | 静态变量 | `@logoUrl` | 字符串:`"https://..."` 或 Base64 |
840
+ | 数组元素 | `@flightRecords[0].image` | 该字段值需为 URL 或 Base64 |
841
+
842
+ **在 sampleData 中对应的数据:**
843
+
844
+ ```json
845
+ {
846
+ "variables": {
847
+ "logoUrl": "https://example.com/logo.png",
848
+ "avatarBase64": "data:image/png;base64,iVBORw0KGgo...",
849
+ "flightRecords": [
850
+ { "image": "https://picsum.photos/id/1/200/80" }
851
+ ]
852
+ }
853
+ }
854
+ ```
855
+
856
+ ### 总结
857
+
858
+ | 方式 | 适用场景 | 存储内容 |
859
+ |------|---------|---------|
860
+ | URL 输入 | 固定图片、CDN 资源 | URL 字符串 |
861
+ | 本地上传 | 无公网链接的图片 | Base64 编码字符串 |
862
+ | 变量绑定 | 每条数据图片不同 | URL 或 Base64 |
863
+
864
+ ---
865
+
581
866
  ## 支持的元素类型
582
867
 
583
868
  | 类型 | 标识 | 说明 |
@@ -1,4 +1,4 @@
1
- import { getDefaultExportFromCjs } from "./web-component-ZD0SqIW-.js";
1
+ import { getDefaultExportFromCjs } from "./web-component-MgGji3qW.js";
2
2
  function _mergeNamespaces(n, m) {
3
3
  for (var i = 0; i < m.length; i++) {
4
4
  const e = m[i];
@@ -1,4 +1,4 @@
1
- import { getDefaultExportFromCjs } from "./web-component-ZD0SqIW-.js";
1
+ import { getDefaultExportFromCjs } from "./web-component-MgGji3qW.js";
2
2
  function _mergeNamespaces(n, m) {
3
3
  for (var i = 0; i < m.length; i++) {
4
4
  const e = m[i];
@@ -1,4 +1,4 @@
1
- import { getDefaultExportFromCjs } from "./web-component-ZD0SqIW-.js";
1
+ import { getDefaultExportFromCjs } from "./web-component-MgGji3qW.js";
2
2
  function _mergeNamespaces(n, m) {
3
3
  for (var i = 0; i < m.length; i++) {
4
4
  const e = m[i];
@@ -1,4 +1,4 @@
1
- import { defineComponent, h, computed, onUnmounted, watch, shallowRef, loader, onMounted, nextTick, ref } from "./web-component-ZD0SqIW-.js";
1
+ import { defineComponent, h, computed, onUnmounted, watch, shallowRef, loader, onMounted, nextTick, ref } from "./web-component-MgGji3qW.js";
2
2
  var __defProp$2 = Object.defineProperty;
3
3
  var __defProps = Object.defineProperties;
4
4
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
@@ -1,4 +1,4 @@
1
- import { commonjsGlobal, getDefaultExportFromCjs } from "./web-component-ZD0SqIW-.js";
1
+ import { commonjsGlobal, getDefaultExportFromCjs } from "./web-component-MgGji3qW.js";
2
2
  import { _typeof as _typeof$1 } from "./typeof-DxTVrAEz.js";
3
3
  var es_promise = {};
4
4
  var es_promise_constructor = {};
@@ -10832,7 +10832,7 @@ function le() {
10832
10832
  var h2 = l2.getContext("2d");
10833
10833
  h2.fillStyle = "#fff", h2.fillRect(0, 0, l2.width, l2.height);
10834
10834
  var f2 = { ignoreMouse: true, ignoreAnimation: true, ignoreDimensions: true }, d2 = this;
10835
- return (i.canvg ? Promise.resolve(i.canvg) : import("./index.es-698hP6_U.js")).catch(function(t3) {
10835
+ return (i.canvg ? Promise.resolve(i.canvg) : import("./index.es-D11_691A.js")).catch(function(t3) {
10836
10836
  return Promise.reject(new Error("Could not load canvg: " + t3));
10837
10837
  }).then(function(t3) {
10838
10838
  return t3.default ? t3.default : t3;
@@ -1,4 +1,4 @@
1
- import { commonjsGlobal, getDefaultExportFromCjs } from "./web-component-ZD0SqIW-.js";
1
+ import { commonjsGlobal, getDefaultExportFromCjs } from "./web-component-MgGji3qW.js";
2
2
  function _mergeNamespaces(n, m) {
3
3
  for (var i = 0; i < m.length; i++) {
4
4
  const e = m[i];
@@ -1 +1 @@
1
- .custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-dacba85f]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.print-renderer[data-v-d181d33d]{padding:0}.animate-fade-in[data-v-4c59b77a]{animation:fadeIn-4c59b77a .2s ease-out}@keyframes fadeIn-4c59b77a{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}[data-v-3e59cbc1] .print-page{margin-bottom:20px;background:#fff;box-shadow:none!important;position:relative!important;left:auto!important;top:auto!important}[data-v-3e59cbc1] .print-page:last-child{margin-bottom:0}.preview-content[data-v-3e59cbc1] *{cursor:default!important}.resize-y[data-v-e19d1803]{resize:vertical}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-a725f100]::-webkit-scrollbar{width:6px}.custom-scrollbar[data-v-a725f100]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-a725f100]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:3px}.custom-scrollbar[data-v-a725f100]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.no-scrollbar[data-v-9e6ec8c1]{-ms-overflow-style:none;scrollbar-width:none}.no-scrollbar[data-v-9e6ec8c1]::-webkit-scrollbar{display:none}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar{width:6px}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:3px}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}
1
+ .custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-74e0e91a]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.print-renderer[data-v-d181d33d]{padding:0}.animate-fade-in[data-v-4c59b77a]{animation:fadeIn-4c59b77a .2s ease-out}@keyframes fadeIn-4c59b77a{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}[data-v-3e59cbc1] .print-page{margin-bottom:20px;background:#fff;box-shadow:none!important;position:relative!important;left:auto!important;top:auto!important}[data-v-3e59cbc1] .print-page:last-child{margin-bottom:0}.preview-content[data-v-3e59cbc1] *{cursor:default!important}.resize-y[data-v-e19d1803]{resize:vertical}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-1e890fd6]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-2ce9799f]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-9d2cf375]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar{width:4px}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:2px}.custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-89c1feca]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}.custom-scrollbar[data-v-df852913]::-webkit-scrollbar{width:6px}.custom-scrollbar[data-v-df852913]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-df852913]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:3px}.custom-scrollbar[data-v-df852913]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.no-scrollbar[data-v-9e6ec8c1]{-ms-overflow-style:none;scrollbar-width:none}.no-scrollbar[data-v-9e6ec8c1]::-webkit-scrollbar{display:none}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar{width:6px}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-track{background:transparent}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb{background-color:#e5e7eb;border-radius:3px}.custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb:hover{background-color:#d1d5db}.dark .custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb{background-color:#374151}.dark .custom-scrollbar[data-v-f18f44fe]::-webkit-scrollbar-thumb:hover{background-color:#4b5563}
@@ -1,4 +1,4 @@
1
- import { PrintDesignerElement } from "./web-component-ZD0SqIW-.js";
1
+ import { PrintDesignerElement } from "./web-component-MgGji3qW.js";
2
2
  export {
3
3
  PrintDesignerElement
4
4
  };