@canvas-components/react-print-design 0.1.1 → 0.1.3

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/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createContext, forwardRef, useRef, useState, useEffect, useMemo, useImperativeHandle, useContext } from 'react';
2
- import { ReactConfigProvider, ReactPopconfirm, ReactPrinterOutlined, ReactButton, ReactSaveOutlined, ReactUndoOutlined, ReactRedoOutlined, ReactZoomOutOutlined, ReactFullscreenOutlined, ReactZoomInOutlined, ReactDatabaseOutlined, ReactEyeOutlined, ReactLeftOutlined, ReactRightOutlined, ReactImportOutlined, ReactDropdown, ReactExportOutlined, ReactBugOutlined, ReactFullscreenExitOutlined, ReactCloseOutlined, ReactResizablePanels, ReactCopyOutlined, ReactDeleteOutlined, ReactCollapsePanel, ReactInputNumber, ReactFontSizeOutlined, ReactLineOutlined, ReactFileImageOutlined, ReactBarcodeOutlined, ReactQrcodeOutlined, ReactDollarOutlined, ReactNumberOutlined, ReactHighlightOutlined, ReactPlusOutlined, ReactTableOutlined, ReactCalendarOutlined, ReactBarChartOutlined, ReactBorderOutlined, ReactSelect, ReactTextArea, ReactInput, ReactCheckbox, ReactColorPicker, ReactRadio, ReactPopup, ReactVerticalAlignBottomOutlined, ReactAlignCenterOutlined, ReactVerticalAlignTopOutlined, ReactAlignRightOutlined, ReactAlignLeftOutlined, ReactSelectOutlined, ReactArrowDownOutlined, ReactArrowUpOutlined, ReactUngroupOutlined, ReactGroupOutlined, ReactEyeInvisibleOutlined, ReactUnlockOutlined, ReactLockOutlined, ReactSnippetsOutlined, ReactScissorOutlined, ReactModal, ReactSortableList, ReactHolderOutlined, ReactFolderOutlined, ReactCollapseMotion, ReactMenuOutlined, ReactColumnWidthOutlined, ReactVerticalAlignMiddleOutlined, ReactCascader, ReactEditOutlined } from '@canvas-components/react-components';
2
+ import { ReactConfigProvider, ReactTour, ReactPopconfirm, ReactPrinterOutlined, ReactButton, ReactSaveOutlined, ReactUndoOutlined, ReactRedoOutlined, ReactZoomOutOutlined, ReactFullscreenOutlined, ReactZoomInOutlined, ReactDatabaseOutlined, ReactEyeOutlined, ReactLeftOutlined, ReactRightOutlined, ReactImportOutlined, ReactDropdown, ReactExportOutlined, ReactBugOutlined, ReactPlayCircleOutlined, ReactFullscreenExitOutlined, ReactCloseOutlined, ReactResizablePanels, ReactCopyOutlined, ReactDeleteOutlined, ReactCollapsePanel, ReactInputNumber, ReactFontSizeOutlined, ReactLineOutlined, ReactFileImageOutlined, ReactBarcodeOutlined, ReactQrcodeOutlined, ReactDollarOutlined, ReactNumberOutlined, ReactHighlightOutlined, ReactPlusOutlined, ReactTableOutlined, ReactCalendarOutlined, ReactBarChartOutlined, ReactBorderOutlined, ReactSelect, ReactTextArea, ReactInput, ReactCheckbox, ReactColorPicker, ReactRadio, ReactPopup, ReactVerticalAlignBottomOutlined, ReactAlignCenterOutlined, ReactVerticalAlignTopOutlined, ReactAlignRightOutlined, ReactAlignLeftOutlined, ReactSelectOutlined, ReactArrowDownOutlined, ReactArrowUpOutlined, ReactUngroupOutlined, ReactGroupOutlined, ReactEyeInvisibleOutlined, ReactUnlockOutlined, ReactLockOutlined, ReactSnippetsOutlined, ReactScissorOutlined, ReactModal, ReactSortableList, ReactHolderOutlined, ReactFolderOutlined, ReactCollapseMotion, ReactMenuOutlined, ReactColumnWidthOutlined, ReactVerticalAlignMiddleOutlined, ReactCascader, ReactEditOutlined } from '@canvas-components/react-components';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { createPrintDesignDocument, PrintDesign, resolvePrintDesignDataPath, parsePrintDesignDocument, formatDisplayUnit, createPrintDesignId, getPrintDesignAlignmentUnits, transformPrintDesignToHtml, createPrintDesignPage, paginatePrintDesignDocument, buildPrintDesignLayerTree, fromDisplayUnit, toDisplayUnit, resolvePrintDesignBinding, resolvePrintDesignElementVisible, normalizeGridCount, getPrintDesignElementDataConfig, getPrintDesignDataFields, renderPrintDesignPageToCanvas, readChartData, isPrintDesignChartDataSource, isPrintDesignTableDataSource, resolveChartOption, resolveGanttTasks, resolveTableDataSource, resolvePivotRows, removePrintPivotField, movePrintPivotField, resolveTableRows, printPivotFieldTitle, findPrintPivotFieldArea, printPivotValueTitle, tableLeafColumns, readTableCell, writeTableCell, resizeGridCells } from '@canvas-components/print-design';
4
+ import { createPrintDesignDocument, PrintDesign, printPrintDesignHtml, transformPrintDesignToHtml, resolvePrintDesignDataPath, parsePrintDesignDocument, formatDisplayUnit, createPrintDesignId, tableLeafColumns, createPrintDesignPage, paginatePrintDesignDocument, buildPrintDesignLayerTree, fromDisplayUnit, toDisplayUnit, getPrintDesignAlignmentUnits, resolvePrintDesignBinding, resolvePrintDesignElementVisible, normalizeGridCount, getPrintDesignElementDataConfig, getPrintDesignDataFields, renderPrintDesignPageToCanvas, readChartData, isPrintDesignChartDataSource, isPrintDesignTableDataSource, resolveChartOption, resolveGanttTasks, resolveTableDataSource, resolvePivotRows, removePrintPivotField, movePrintPivotField, resolveTableRows, printPivotFieldTitle, findPrintPivotFieldArea, printPivotValueTitle, readTableCell, writeTableCell, resizeGridCells } from '@canvas-components/print-design';
5
5
  import { encodeBarcodePattern } from '@canvas-components/barcode';
6
6
  import { getQrCodeMatrix, buildQrCodeContent } from '@canvas-components/qrcode';
7
7
  import { zipSync } from 'fflate';
@@ -343,7 +343,7 @@ function createCustomComponent(id, name, elements) {
343
343
  }
344
344
 
345
345
  // src/features/context-menu/menu-items.ts
346
- function buildPrintDesignMenuItems(page, ids, readonly, instance, onSaveGroup) {
346
+ function buildPrintDesignMenuItems(page, ids, readonly, instance, onSaveGroup, tableCell, tableSelector) {
347
347
  const selected = page.elements.filter((item) => ids.includes(item.id));
348
348
  const hasSelection = selected.length > 0;
349
349
  const locked = selected.some((item) => item.locked);
@@ -395,47 +395,167 @@ function buildPrintDesignMenuItems(page, ids, readonly, instance, onSaveGroup) {
395
395
  }
396
396
  }
397
397
  ];
398
- if (hasSelection) {
398
+ const range = instance?.getTableCellSelection();
399
+ const selectedRange = range && selected.some(
400
+ (item) => item.type === "table" && item.id === range.elementId
401
+ ) ? range : null;
402
+ const targetCell = tableSelector ? null : tableCell ?? (selectedRange && !selectedRange.selectorKind ? {
403
+ elementId: selectedRange.elementId,
404
+ area: selectedRange.area,
405
+ rowIndex: selectedRange.endRow,
406
+ columnIndex: selectedRange.endColumn
407
+ } : null);
408
+ if (tableSelector) {
409
+ const table = page.elements.find(
410
+ (item) => item.id === tableSelector.elementId
411
+ );
412
+ const noRowEdit = noEdit || table?.type !== "table" || table.dataMode === "binding";
413
+ if (tableSelector.kind === "row" && tableSelector.area === "body")
414
+ items.push(
415
+ {
416
+ key: "insertRowAbove",
417
+ label: "\u5728\u4E0A\u65B9\u65B0\u589E\u884C",
418
+ separator: true,
419
+ disabled: noRowEdit,
420
+ run: (i) => {
421
+ i.insertTableRow(
422
+ tableSelector.elementId,
423
+ tableSelector.index,
424
+ false
425
+ );
426
+ }
427
+ },
428
+ {
429
+ key: "insertRowBelow",
430
+ label: "\u5728\u4E0B\u65B9\u65B0\u589E\u884C",
431
+ disabled: noRowEdit,
432
+ run: (i) => {
433
+ i.insertTableRow(
434
+ tableSelector.elementId,
435
+ tableSelector.index,
436
+ true
437
+ );
438
+ }
439
+ }
440
+ );
441
+ if (tableSelector.kind === "column")
442
+ items.push(
443
+ {
444
+ key: "insertColumnLeft",
445
+ label: "\u5728\u5DE6\u4FA7\u65B0\u589E\u5217",
446
+ separator: true,
447
+ disabled: noEdit,
448
+ run: (i) => {
449
+ i.insertTableColumn(
450
+ tableSelector.elementId,
451
+ tableSelector.index,
452
+ false
453
+ );
454
+ }
455
+ },
456
+ {
457
+ key: "insertColumnRight",
458
+ label: "\u5728\u53F3\u4FA7\u65B0\u589E\u5217",
459
+ disabled: noEdit,
460
+ run: (i) => {
461
+ i.insertTableColumn(
462
+ tableSelector.elementId,
463
+ tableSelector.index,
464
+ true
465
+ );
466
+ }
467
+ }
468
+ );
469
+ if (tableSelector.kind === "all" && table?.type === "table")
470
+ items.push(
471
+ {
472
+ key: "appendRow",
473
+ label: "\u65B0\u589E\u884C",
474
+ separator: true,
475
+ disabled: noRowEdit,
476
+ run: (i) => {
477
+ i.insertTableRow(
478
+ tableSelector.elementId,
479
+ table.dataSource.length - 1,
480
+ true
481
+ );
482
+ }
483
+ },
484
+ {
485
+ key: "appendColumn",
486
+ label: "\u65B0\u589E\u5217",
487
+ disabled: noEdit,
488
+ run: (i) => {
489
+ i.insertTableColumn(
490
+ tableSelector.elementId,
491
+ tableLeafColumns(table.columns).filter((column) => !column.hidden).length - 1,
492
+ true
493
+ );
494
+ }
495
+ }
496
+ );
497
+ }
498
+ if (targetCell) {
499
+ const sameTable = selectedRange?.elementId === targetCell.elementId && (selectedRange.area ?? "body") === (targetCell.area ?? "body");
500
+ const merge = (i, row, column, rows, columns) => {
501
+ if (targetCell.area === "header")
502
+ i.mergeTableHeaderCell(
503
+ targetCell.elementId,
504
+ row,
505
+ column,
506
+ rows,
507
+ columns
508
+ );
509
+ else i.mergeTableCell(targetCell.elementId, row, column, rows, columns);
510
+ };
511
+ const startRow = sameTable ? Math.min(selectedRange.startRow, selectedRange.endRow) : targetCell.rowIndex;
512
+ const startColumn = sameTable ? Math.min(selectedRange.startColumn, selectedRange.endColumn) : targetCell.columnIndex;
513
+ const rowSpan = sameTable ? Math.abs(selectedRange.endRow - selectedRange.startRow) + 1 : 1;
514
+ const colSpan = sameTable ? Math.abs(selectedRange.endColumn - selectedRange.startColumn) + 1 : 1;
399
515
  items.push(
400
516
  {
401
- key: "duplicate",
402
- label: "\u751F\u6210\u526F\u672C",
403
- disabled: readonly,
517
+ key: "mergeCells",
518
+ label: "\u5408\u5E76\u9009\u4E2D\u5355\u5143\u683C",
519
+ separator: true,
520
+ disabled: readonly || locked || !!selectedRange?.selectorKind || rowSpan * colSpan < 2,
404
521
  run: (i) => {
405
- i.duplicateElements();
522
+ merge(i, startRow, startColumn, rowSpan, colSpan);
406
523
  }
407
524
  },
408
525
  {
409
- key: "front",
410
- label: "\u7F6E\u9876",
411
- separator: true,
412
- disabled: noEdit,
526
+ key: "mergeRight",
527
+ label: "\u4E0E\u53F3\u4FA7\u5355\u5143\u683C\u5408\u5E76",
528
+ disabled: readonly || locked,
413
529
  run: (i) => {
414
- i.moveSelectionLayer("front");
530
+ merge(i, targetCell.rowIndex, targetCell.columnIndex, 1, 2);
415
531
  }
416
532
  },
417
533
  {
418
- key: "forward",
419
- label: "\u4E0A\u79FB\u4E00\u5C42",
420
- disabled: noEdit,
534
+ key: "mergeDown",
535
+ label: "\u4E0E\u4E0B\u65B9\u5355\u5143\u683C\u5408\u5E76",
536
+ disabled: readonly || locked,
421
537
  run: (i) => {
422
- i.moveSelectionLayer("forward");
538
+ merge(i, targetCell.rowIndex, targetCell.columnIndex, 2, 1);
423
539
  }
424
540
  },
425
541
  {
426
- key: "backward",
427
- label: "\u4E0B\u79FB\u4E00\u5C42",
428
- disabled: noEdit,
542
+ key: "unmergeCell",
543
+ label: "\u53D6\u6D88\u5355\u5143\u683C\u5408\u5E76",
544
+ disabled: readonly || locked,
429
545
  run: (i) => {
430
- i.moveSelectionLayer("backward");
546
+ merge(i, targetCell.rowIndex, targetCell.columnIndex, 1, 1);
431
547
  }
432
- },
548
+ }
549
+ );
550
+ }
551
+ if (hasSelection) {
552
+ items.push(
433
553
  {
434
- key: "back",
435
- label: "\u7F6E\u5E95",
436
- disabled: noEdit,
554
+ key: "duplicate",
555
+ label: "\u751F\u6210\u526F\u672C",
556
+ disabled: readonly,
437
557
  run: (i) => {
438
- i.moveSelectionLayer("back");
558
+ i.duplicateElements();
439
559
  }
440
560
  },
441
561
  {
@@ -463,28 +583,6 @@ function buildPrintDesignMenuItems(page, ids, readonly, instance, onSaveGroup) {
463
583
  disabled: readonly,
464
584
  run: () => onSaveGroup(selectedGroup.name, selectedGroup.elements)
465
585
  });
466
- const alignmentUnits = getPrintDesignAlignmentUnits(page.elements, ids);
467
- for (const [key, label] of [
468
- ["left", "\u5DE6\u5BF9\u9F50"],
469
- ["center", "\u6C34\u5E73\u5C45\u4E2D"],
470
- ["right", "\u53F3\u5BF9\u9F50"],
471
- ["top", "\u9876\u5BF9\u9F50"],
472
- ["middle", "\u5782\u76F4\u5C45\u4E2D"],
473
- ["bottom", "\u5E95\u5BF9\u9F50"],
474
- ["justify-horizontal", "\u6C34\u5E73\u4E24\u7AEF\u5BF9\u9F50\uFF08\u7B49\u95F4\u8DDD\uFF09"],
475
- ["distribute-horizontal", "\u6C34\u5E73\u5206\u6563\u5BF9\u9F50\uFF08\u7B49\u4E2D\u5FC3\u8DDD\uFF09"],
476
- ["justify-vertical", "\u5782\u76F4\u4E24\u7AEF\u5BF9\u9F50\uFF08\u7B49\u95F4\u8DDD\uFF09"],
477
- ["distribute-vertical", "\u5782\u76F4\u5206\u6563\u5BF9\u9F50\uFF08\u7B49\u4E2D\u5FC3\u8DDD\uFF09"]
478
- ])
479
- items.push({
480
- key,
481
- label,
482
- separator: key === "left",
483
- disabled: noEdit || key.includes("-") && alignmentUnits.length < 3,
484
- run: (i) => {
485
- i.alignSelection(key);
486
- }
487
- });
488
586
  const allLocked = selected.every((item) => item.locked), allHidden = selected.every((item) => item.visible === false);
489
587
  items.push(
490
588
  {
@@ -1249,6 +1347,7 @@ function ElementLayerList(props) {
1249
1347
  });
1250
1348
  },
1251
1349
  className: `cc-print-design-layer-item${node.memberIds.every((id) => props.selectedIds.includes(id)) ? " selected" : ""}`,
1350
+ "data-tour-element-id": node.element.id,
1252
1351
  children: [
1253
1352
  /* @__PURE__ */ jsx(
1254
1353
  "button",
@@ -1452,7 +1551,11 @@ function isTableColumns(value) {
1452
1551
  return Array.isArray(value) && value.every(
1453
1552
  (column) => column && typeof column === "object" && (typeof column.dataIndex === "string" || Array.isArray(column.dataIndex) && column.dataIndex.every(
1454
1553
  (v) => typeof v === "string" || typeof v === "number"
1455
- )) && (column.width == null || Number.isFinite(column.width) && column.width > 0) && (column.cellType == null || tableCellTypes.includes(column.cellType)) && (column.children == null || isTableColumns(column.children))
1554
+ )) && (column.width == null || Number.isFinite(column.width) && column.width > 0) && (column.cellOverflow == null || ["nowrap", "wrap", "ellipsis", "shrink"].includes(
1555
+ column.cellOverflow
1556
+ )) && (column.cellPadding == null || typeof column.cellPadding === "object" && ["top", "right", "bottom", "left"].every(
1557
+ (side) => column.cellPadding[side] == null || Number.isFinite(column.cellPadding[side]) && column.cellPadding[side] >= 0
1558
+ )) && (column.cellType == null || tableCellTypes.includes(column.cellType)) && (column.children == null || isTableColumns(column.children))
1456
1559
  );
1457
1560
  }
1458
1561
  var tableCellTypeLabels = {
@@ -1889,8 +1992,10 @@ var TABLE_VERTICAL_ALIGN_OPTIONS = [
1889
1992
  { value: "bottom", label: "\u5E95\u90E8" }
1890
1993
  ];
1891
1994
  var TABLE_OVERFLOW_OPTIONS = [
1995
+ { value: "nowrap", label: "\u8D85\u51FA\u88C1\u5207" },
1892
1996
  { value: "wrap", label: "\u81EA\u52A8\u6362\u884C" },
1893
- { value: "ellipsis", label: "\u7701\u7565\u53F7" }
1997
+ { value: "ellipsis", label: "\u8D85\u51FA\u663E\u793A..." },
1998
+ { value: "shrink", label: "\u538B\u7F29\u5B57\u5F62" }
1894
1999
  ];
1895
2000
  var TABLE_SUMMARY_OPTIONS = [
1896
2001
  { value: "none", label: "\u65E0" },
@@ -2444,6 +2549,7 @@ function LeftPanel(props) {
2444
2549
  {
2445
2550
  type: "button",
2446
2551
  className: "cc-print-design-component-item",
2552
+ "data-component-type": type,
2447
2553
  disabled: props.contentReadonly,
2448
2554
  draggable: !props.contentReadonly,
2449
2555
  onDragStart: (event) => startComponentDrag(event, type),
@@ -2469,6 +2575,7 @@ function LeftPanel(props) {
2469
2575
  {
2470
2576
  type: "button",
2471
2577
  className: "cc-print-design-component-item",
2578
+ "data-component-type": type,
2472
2579
  disabled: props.contentReadonly,
2473
2580
  draggable: !props.contentReadonly,
2474
2581
  onDragStart: (event) => startComponentDrag(event, type),
@@ -2494,6 +2601,7 @@ function LeftPanel(props) {
2494
2601
  {
2495
2602
  type: "button",
2496
2603
  className: "cc-print-design-component-item",
2604
+ "data-component-type": type,
2497
2605
  disabled: props.contentReadonly,
2498
2606
  draggable: !props.contentReadonly,
2499
2607
  onDragStart: (event) => startComponentDrag(event, type),
@@ -2519,6 +2627,7 @@ function LeftPanel(props) {
2519
2627
  {
2520
2628
  type: "button",
2521
2629
  className: "cc-print-design-component-item",
2630
+ "data-component-type": "shape",
2522
2631
  disabled: props.contentReadonly,
2523
2632
  draggable: !props.contentReadonly,
2524
2633
  onDragStart: (event) => startComponentDrag(event, "shape", shape),
@@ -2544,6 +2653,7 @@ function LeftPanel(props) {
2544
2653
  {
2545
2654
  type: "button",
2546
2655
  className: "cc-print-design-component-item",
2656
+ "data-component-type": "ruler",
2547
2657
  disabled: props.contentReadonly,
2548
2658
  draggable: !props.contentReadonly,
2549
2659
  onDragStart: (event) => startComponentDrag(event, "ruler", orientation),
@@ -2569,6 +2679,7 @@ function LeftPanel(props) {
2569
2679
  {
2570
2680
  type: "button",
2571
2681
  className: "cc-print-design-component-item",
2682
+ "data-component-type": "grid",
2572
2683
  disabled: props.contentReadonly,
2573
2684
  draggable: !props.contentReadonly,
2574
2685
  onDragStart: (event) => startComponentDrag(event, "grid"),
@@ -2593,6 +2704,7 @@ function LeftPanel(props) {
2593
2704
  {
2594
2705
  type: "button",
2595
2706
  className: "cc-print-design-component-item",
2707
+ "data-component-type": "progress",
2596
2708
  disabled: props.contentReadonly,
2597
2709
  draggable: !props.contentReadonly,
2598
2710
  onDragStart: (event) => startComponentDrag(event, "progress", variant),
@@ -2618,6 +2730,7 @@ function LeftPanel(props) {
2618
2730
  {
2619
2731
  type: "button",
2620
2732
  className: "cc-print-design-component-item",
2733
+ "data-component-type": "list",
2621
2734
  disabled: props.contentReadonly,
2622
2735
  draggable: !props.contentReadonly,
2623
2736
  onDragStart: (event) => startComponentDrag(event, "list", style),
@@ -2643,6 +2756,7 @@ function LeftPanel(props) {
2643
2756
  {
2644
2757
  type: "button",
2645
2758
  className: "cc-print-design-component-item",
2759
+ "data-component-type": "chart",
2646
2760
  disabled: props.contentReadonly,
2647
2761
  draggable: !props.contentReadonly,
2648
2762
  onDragStart: (event) => startComponentDrag(event, "chart", preset.id),
@@ -2856,42 +2970,86 @@ function elementIcon(type) {
2856
2970
  const Icon = iconByType[type] ?? ReactBorderOutlined;
2857
2971
  return /* @__PURE__ */ jsx(Icon, { "aria-hidden": "true" });
2858
2972
  }
2859
- function usePrintPreviewPages(document2, records, enabled) {
2973
+ function usePrintPreviewPages(document2, records, enabled, loadData) {
2860
2974
  const [pages, setPages] = useState([]);
2861
2975
  const [processed, setProcessed] = useState(0);
2862
2976
  const [error, setError] = useState("");
2977
+ const [loading, setLoading] = useState(false);
2978
+ const [progress, setProgress] = useState("");
2979
+ const [source, setSource] = useState(null);
2863
2980
  useEffect(() => {
2864
- if (!enabled) return;
2865
- let cancelled = false;
2981
+ if (!enabled) {
2982
+ setPages([]);
2983
+ setSource(null);
2984
+ setLoading(false);
2985
+ return;
2986
+ }
2987
+ const controller = new AbortController();
2866
2988
  setPages([]);
2867
2989
  setProcessed(0);
2868
2990
  setError("");
2991
+ setLoading(true);
2992
+ setProgress("\u6B63\u5728\u51C6\u5907\u9884\u89C8\u2026");
2993
+ setSource(null);
2869
2994
  const build = async () => {
2870
2995
  const pending = [];
2871
2996
  try {
2872
- for (let position = 0; position < records.length; position++) {
2873
- if (cancelled) return;
2874
- const data = records[position];
2875
- const result = paginatePrintDesignDocument(document2, data);
2876
- if (cancelled) return;
2877
- pending.push(...result.pages.map((page) => ({ page, data })));
2878
- if (position === 0 || position % 8 === 7 || position === records.length - 1) {
2879
- setPages([...pending]);
2880
- setProcessed(position + 1);
2881
- await new Promise((resolve) => setTimeout(resolve, 0));
2997
+ let progressTime = 0;
2998
+ const loaded = loadData ? await loadData(document2, {
2999
+ signal: controller.signal,
3000
+ onProgress: (completed, total) => {
3001
+ const now = performance.now();
3002
+ if (!controller.signal.aborted && (now - progressTime > 100 || completed === total)) {
3003
+ progressTime = now;
3004
+ setProgress(`\u6B63\u5728\u51C6\u5907\u9884\u89C8 ${completed} / ${total}`);
3005
+ }
2882
3006
  }
3007
+ }) : null;
3008
+ controller.signal.throwIfAborted();
3009
+ if (loaded) setSource(loaded);
3010
+ const previewDocument = loaded?.document ?? document2;
3011
+ const previewRecords = loaded ? [loaded.data] : records;
3012
+ let deadline = performance.now() + 8;
3013
+ let publishedAt = 0;
3014
+ for (let position = 0; position < previewRecords.length; position++) {
3015
+ const data = previewRecords[position];
3016
+ for (const page of previewDocument.pages) {
3017
+ controller.signal.throwIfAborted();
3018
+ const result = paginatePrintDesignDocument(
3019
+ { ...previewDocument, pages: [page] },
3020
+ data
3021
+ );
3022
+ for (const page2 of result.pages) pending.push({ page: page2, data });
3023
+ if (performance.now() >= deadline) {
3024
+ if (performance.now() - publishedAt > 100) {
3025
+ setPages([...pending]);
3026
+ setProgress(`\u6B63\u5728\u751F\u6210\u9884\u89C8\uFF0C\u5DF2\u751F\u6210 ${pending.length} \u9875`);
3027
+ publishedAt = performance.now();
3028
+ }
3029
+ await new Promise((resolve) => setTimeout(resolve, 0));
3030
+ deadline = performance.now() + 8;
3031
+ }
3032
+ }
3033
+ setProcessed(position + 1);
2883
3034
  }
3035
+ controller.signal.throwIfAborted();
3036
+ setPages(pending);
3037
+ setLoading(false);
3038
+ setProgress("");
2884
3039
  } catch (cause) {
2885
- if (!cancelled)
3040
+ if (!controller.signal.aborted) {
2886
3041
  setError(cause instanceof Error ? cause.message : "\u751F\u6210\u9884\u89C8\u5931\u8D25");
3042
+ setLoading(false);
3043
+ }
2887
3044
  }
2888
3045
  };
2889
- void build();
3046
+ const timer = setTimeout(() => void build(), 0);
2890
3047
  return () => {
2891
- cancelled = true;
3048
+ clearTimeout(timer);
3049
+ controller.abort();
2892
3050
  };
2893
- }, [document2, records, enabled]);
2894
- return { pages, processed, error };
3051
+ }, [document2, records, enabled, loadData]);
3052
+ return { pages, processed, error, loading, progress, source };
2895
3053
  }
2896
3054
  function SaveCustomComponentDialog({
2897
3055
  defaultName,
@@ -2942,6 +3100,211 @@ function SaveCustomComponentDialog({
2942
3100
  }
2943
3101
  );
2944
3102
  }
3103
+
3104
+ // src/features/templates/template-tour.ts
3105
+ var typeNames = {
3106
+ text: "\u6587\u672C",
3107
+ list: "\u5217\u8868",
3108
+ dateTime: "\u65E5\u671F\u65F6\u95F4",
3109
+ moneyUpper: "\u91D1\u989D\u5927\u5199",
3110
+ pageNumber: "\u9875\u7801",
3111
+ watermark: "\u6C34\u5370",
3112
+ shape: "\u5F62\u72B6",
3113
+ divider: "\u5206\u5272\u7EBF",
3114
+ ruler: "\u6807\u5C3A",
3115
+ grid: "\u7F51\u683C",
3116
+ progress: "\u8FDB\u5EA6\u6761",
3117
+ clock: "\u65F6\u949F",
3118
+ image: "\u56FE\u7247",
3119
+ barcode: "\u6761\u7801",
3120
+ qrcode: "\u4E8C\u7EF4\u7801",
3121
+ chart: "\u56FE\u8868",
3122
+ table: "\u8868\u683C",
3123
+ pivotTable: "\u900F\u89C6\u8868",
3124
+ gantt: "\u7518\u7279\u56FE"
3125
+ };
3126
+ function getTourFields(element) {
3127
+ const fields = [];
3128
+ const values = element;
3129
+ const add = (key, label) => {
3130
+ if (values[key] !== void 0)
3131
+ fields.push({ key, label, value: values[key] });
3132
+ };
3133
+ add("name", "\u56FE\u5C42\u540D\u79F0");
3134
+ add("x", "X \u5750\u6807");
3135
+ add("y", "Y \u5750\u6807");
3136
+ add("width", "\u5BBD\u5EA6");
3137
+ add("height", "\u9AD8\u5EA6");
3138
+ add("rotation", "\u65CB\u8F6C");
3139
+ add("overflowPolicy", "\u8D85\u51FA\u7EB8\u5F20\u5904\u7406");
3140
+ if (element.type === "text") {
3141
+ add("text", "\u6587\u672C\u5185\u5BB9");
3142
+ add("fontSize", "\u5B57\u53F7");
3143
+ add("color", "\u6587\u5B57\u989C\u8272");
3144
+ }
3145
+ if (element.type === "table") {
3146
+ add("columns", "\u5217\u914D\u7F6E JSON");
3147
+ add("dataMode", "\u6570\u636E\u65B9\u5F0F");
3148
+ if (element.dataMode === "binding") add("dataPath", "\u8868\u683C\u6570\u636E\u6E90\u8DEF\u5F84");
3149
+ if (element.dataMode === "binding")
3150
+ add("fallbackToStatic", "\u6570\u636E\u6E90\u7F3A\u5931\u65F6\u4F7F\u7528\u9ED8\u8BA4\u5185\u5BB9");
3151
+ if (element.dataMode !== "binding" || element.fallbackToStatic)
3152
+ add("dataSource", "\u6570\u636E\u5185\u5BB9 JSON");
3153
+ add("showHeader", "\u663E\u793A\u8868\u5934");
3154
+ add("headerRowHeight", "\u8868\u5934\u884C\u9AD8");
3155
+ add("rowHeight", "\u6570\u636E\u884C\u9AD8");
3156
+ add("printRowCount", "\u6BCF\u9875\u884C\u6570");
3157
+ add("borderMode", "\u6253\u5370\u8FB9\u6846");
3158
+ if (element.borderMode === "binding") add("borderPath", "\u8FB9\u6846\u6570\u636E\u5B57\u6BB5");
3159
+ add("cellBorder", "\u5355\u5143\u683C\u8FB9\u6846\u5BBD\u5EA6");
3160
+ add("mergeCell", "\u8FDE\u7EED\u884C\u5206\u7EC4\u5B57\u6BB5");
3161
+ }
3162
+ if (element.type === "pivotTable" || element.type === "gantt") {
3163
+ add("dataMode", "\u6570\u636E\u65B9\u5F0F");
3164
+ if (element.dataMode === "binding") add("dataPath", "\u6570\u636E\u6E90\u8DEF\u5F84");
3165
+ }
3166
+ if (element.type !== "text" && element.type !== "table") {
3167
+ if (element.type !== "shape" && element.type !== "list" && element.type !== "ruler" && element.type !== "grid" && element.type !== "progress") {
3168
+ add("text", "\u6587\u672C\u5185\u5BB9");
3169
+ add("value", "\u5185\u5BB9\u503C");
3170
+ }
3171
+ if (element.type === "pageNumber") add("prefix", "\u9875\u7801\u524D\u7F00");
3172
+ if (element.type === "image") add("src", "\u56FE\u7247\u5730\u5740");
3173
+ }
3174
+ if (element.dataConfig?.mode === "binding") {
3175
+ fields.push({
3176
+ key: "dataConfig.mode",
3177
+ label: "\u6570\u636E\u65B9\u5F0F",
3178
+ value: "binding"
3179
+ });
3180
+ Object.entries(element.dataConfig.bindings ?? {}).forEach(
3181
+ ([key, value]) => fields.push({
3182
+ key: `dataConfig.bindings.${key}`,
3183
+ label: `${key}\u7ED1\u5B9A\u8DEF\u5F84`,
3184
+ value
3185
+ })
3186
+ );
3187
+ }
3188
+ return fields;
3189
+ }
3190
+ function formatTourValue(field) {
3191
+ if (field.key === "columns" && Array.isArray(field.value))
3192
+ return `${field.value.length} \u5217`;
3193
+ if (field.key === "dataSource" && Array.isArray(field.value))
3194
+ return `${field.value.length} \u6761\u8BB0\u5F55`;
3195
+ if (field.key === "mergeCell") return "\u6309\u5B57\u6BB5\u5408\u5E76\u8FDE\u7EED\u5355\u5143\u683C";
3196
+ if (field.key === "cellBorder" && field.value && typeof field.value === "object")
3197
+ return `${field.value.width ?? 1} px`;
3198
+ if (typeof field.value === "boolean") return field.value ? "\u5F00\u542F" : "\u5173\u95ED";
3199
+ return String(field.value ?? "").slice(0, 100);
3200
+ }
3201
+ function createPrintDesignTourSteps(document2) {
3202
+ const steps = [
3203
+ {
3204
+ title: `${document2.name} \xB7 \u5B9E\u73B0\u5206\u6790`,
3205
+ description: `\u4ECE\u7A7A\u767D\u753B\u5E03\u5F00\u59CB\uFF0C\u4F9D\u6B21\u64CD\u4F5C\u5DE6\u4FA7\u7EC4\u4EF6\u9762\u677F\u3001\u753B\u5E03\u3001\u53F3\u4FA7\u5C5E\u6027\u9762\u677F\u548C\u56FE\u5C42\u5217\u8868\uFF0C\u5B8C\u6210 ${document2.pages.length} \u9875\u6A21\u677F\u3002\u6F14\u793A\u7ED3\u675F\u540E\u6062\u590D\u5F53\u524D\u6A21\u677F\u3002`,
3206
+ target: ".cc-print-design-brand",
3207
+ operation: "intro"
3208
+ }
3209
+ ];
3210
+ document2.pages.forEach((page, pageIndex) => {
3211
+ steps.push({
3212
+ title: `\u7B2C ${pageIndex + 1} \u9875 \xB7 \u65B0\u589E\u5E76\u914D\u7F6E\u9875\u9762`,
3213
+ description: `\u5728\u5DE6\u4FA7\u300C\u9875\u9762\u300D\u9762\u677F\u65B0\u589E\u9875\u9762\uFF0C\u8BBE\u7F6E\u7EB8\u5F20 ${page.width} \xD7 ${page.height} mm\uFF0C\u65B9\u5411\u4E3A${page.orientation === "landscape" ? "\u6A2A\u5411" : "\u7EB5\u5411"}\u3002${page.margins ? `\u9875\u8FB9\u8DDD\uFF08\u4E0A/\u53F3/\u4E0B/\u5DE6\uFF09\uFF1A${page.margins.top}/${page.margins.right}/${page.margins.bottom}/${page.margins.left} mm\u3002` : ""}`,
3214
+ target: ".cc-print-design-left-panel",
3215
+ operation: "page",
3216
+ pageIndex,
3217
+ pageId: page.id
3218
+ });
3219
+ page.elements.forEach((element, elementIndex) => {
3220
+ const title = `${pageIndex + 1}.${elementIndex + 1} ${element.name || typeNames[element.type] || element.type}`;
3221
+ const location = {
3222
+ pageIndex,
3223
+ elementIndex,
3224
+ pageId: page.id,
3225
+ elementId: element.id
3226
+ };
3227
+ steps.push(
3228
+ {
3229
+ ...location,
3230
+ operation: "select",
3231
+ title: `${title} \xB7 \u9009\u62E9\u7EC4\u4EF6`,
3232
+ description: `\u6253\u5F00\u5DE6\u4FA7\u300C\u7EC4\u4EF6\u300D\u9762\u677F\uFF0C\u627E\u5230\u300C${typeNames[element.type] || element.type}\u300D\u5E76\u51C6\u5907\u6DFB\u52A0\u3002`,
3233
+ target: `.cc-print-design-component-item[data-component-type="${element.type}"]`
3234
+ },
3235
+ {
3236
+ ...location,
3237
+ operation: "add",
3238
+ title: `${title} \xB7 \u65B0\u589E\u56FE\u5C42`,
3239
+ description: "\u70B9\u51FB\u5DE6\u4FA7\u7EC4\u4EF6\u6216\u62D6\u5230\u753B\u5E03\uFF0C\u5148\u521B\u5EFA\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E\u7684\u56FE\u5C42\u3002\u63A5\u4E0B\u6765\u9010\u9879\u586B\u5199\u53F3\u4FA7\u5C5E\u6027\u3002",
3240
+ target: ".cc-print-design-canvas-frame"
3241
+ },
3242
+ ...getTourFields(element).map(
3243
+ (field, fieldIndex) => ({
3244
+ ...location,
3245
+ operation: "field",
3246
+ fieldIndex,
3247
+ fieldKey: field.key,
3248
+ title: `${title} \xB7 \u914D\u7F6E\u300C${field.label}\u300D`,
3249
+ description: `\u5728\u53F3\u4FA7\u5C5E\u6027\u9762\u677F\u7684\u300C${field.label}\u300D\u8868\u5355\u9879\u4E2D\u8BBE\u7F6E\uFF1A${formatTourValue(field)}\u3002`,
3250
+ target: `.cc-print-design-properties-host [data-tour-field="${field.key}"]`
3251
+ })
3252
+ ),
3253
+ {
3254
+ ...location,
3255
+ operation: "layer",
3256
+ title: `${title} \xB7 \u68C0\u67E5\u56FE\u5C42`,
3257
+ description: `\u5207\u6362\u5DE6\u4FA7\u300C\u56FE\u5C42\u300D\u9762\u677F\uFF0C\u786E\u8BA4\u300C${element.name || typeNames[element.type] || element.type}\u300D\u5DF2\u52A0\u5165\u7B2C ${pageIndex + 1} \u9875\uFF0C\u5E76\u4FDD\u6301\u5F53\u524D\u5C42\u53E0\u987A\u5E8F\u3002`,
3258
+ target: ".cc-print-design-left-panel"
3259
+ }
3260
+ );
3261
+ });
3262
+ });
3263
+ return steps;
3264
+ }
3265
+ function createPrintDesignTourDocument(source, step) {
3266
+ if (step.operation === "intro")
3267
+ return { ...source, pages: [{ ...source.pages[0], elements: [] }] };
3268
+ const pageIndex = step.pageIndex ?? 0;
3269
+ const pages = source.pages.slice(0, pageIndex + 1).map((page, index) => {
3270
+ if (index < pageIndex) return page;
3271
+ if (step.operation === "page") return { ...page, elements: [] };
3272
+ const elementIndex = step.elementIndex ?? 0;
3273
+ const elements = page.elements.slice(0, elementIndex);
3274
+ if (step.operation !== "select") {
3275
+ const element = page.elements[elementIndex];
3276
+ elements.push(
3277
+ step.operation === "add" || step.operation === "field" ? createTourElement(element, step) : element
3278
+ );
3279
+ }
3280
+ return { ...page, elements };
3281
+ });
3282
+ return { ...source, pages };
3283
+ }
3284
+ function createTourElement(element, step) {
3285
+ const draft = {
3286
+ ...createDefaultPrintDesignElement(element.type),
3287
+ id: element.id
3288
+ };
3289
+ if (step.operation === "field") {
3290
+ for (const field of getTourFields(element).slice(
3291
+ 0,
3292
+ (step.fieldIndex ?? -1) + 1
3293
+ )) {
3294
+ if (field.key === "dataConfig.mode") {
3295
+ draft.dataConfig = { mode: field.value, bindings: {} };
3296
+ } else if (field.key.startsWith("dataConfig.bindings.")) {
3297
+ const config = draft.dataConfig ?? {
3298
+ mode: "binding",
3299
+ bindings: {}
3300
+ };
3301
+ config.bindings[field.key.slice("dataConfig.bindings.".length)] = String(field.value);
3302
+ draft.dataConfig = config;
3303
+ } else draft[field.key] = field.value;
3304
+ }
3305
+ }
3306
+ return draft;
3307
+ }
2945
3308
  function PrintExportNameDialog({
2946
3309
  format,
2947
3310
  defaultFileName,
@@ -3155,32 +3518,39 @@ function NameField(props) {
3155
3518
  if (!props.disabled && (name || props.allowEmpty) && name !== props.value)
3156
3519
  props.onCommit(name);
3157
3520
  };
3158
- return /* @__PURE__ */ jsxs("label", { className: "cc-print-design-field cc-print-design-field-full", children: [
3159
- /* @__PURE__ */ jsx("span", { children: props.label }),
3160
- /* @__PURE__ */ jsx(
3161
- ReactInput,
3162
- {
3163
- "aria-label": props.label,
3164
- value: draft,
3165
- disabled: props.disabled,
3166
- onChange: (event) => setDraft(event.target.value),
3167
- onBlur: commit,
3168
- onKeyDown: (event) => {
3169
- if (event.nativeEvent.isComposing) return;
3170
- if (event.key === "Enter") {
3171
- event.preventDefault();
3172
- event.currentTarget.blur();
3173
- } else if (event.key === "Escape") {
3174
- event.preventDefault();
3175
- event.stopPropagation();
3176
- cancelled.current = true;
3177
- setDraft(props.value);
3178
- event.currentTarget.blur();
3521
+ return /* @__PURE__ */ jsxs(
3522
+ "label",
3523
+ {
3524
+ className: "cc-print-design-field cc-print-design-field-full",
3525
+ "data-tour-field": "name",
3526
+ children: [
3527
+ /* @__PURE__ */ jsx("span", { children: props.label }),
3528
+ /* @__PURE__ */ jsx(
3529
+ ReactInput,
3530
+ {
3531
+ "aria-label": props.label,
3532
+ value: draft,
3533
+ disabled: props.disabled,
3534
+ onChange: (event) => setDraft(event.target.value),
3535
+ onBlur: commit,
3536
+ onKeyDown: (event) => {
3537
+ if (event.nativeEvent.isComposing) return;
3538
+ if (event.key === "Enter") {
3539
+ event.preventDefault();
3540
+ event.currentTarget.blur();
3541
+ } else if (event.key === "Escape") {
3542
+ event.preventDefault();
3543
+ event.stopPropagation();
3544
+ cancelled.current = true;
3545
+ setDraft(props.value);
3546
+ event.currentTarget.blur();
3547
+ }
3548
+ }
3179
3549
  }
3180
- }
3181
- }
3182
- )
3183
- ] });
3550
+ )
3551
+ ]
3552
+ }
3553
+ );
3184
3554
  }
3185
3555
  function ElementLayerControls({
3186
3556
  index,
@@ -3718,53 +4088,68 @@ function TableRowSettingsPanel({
3718
4088
  className: "cc-print-design-property-section",
3719
4089
  contentClassName: "cc-print-design-table-data cc-print-design-row-settings",
3720
4090
  children: [
3721
- /* @__PURE__ */ jsx(
4091
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "showHeader", children: /* @__PURE__ */ jsx(
3722
4092
  ReactCheckbox,
3723
4093
  {
3724
4094
  checked: element.showHeader !== false,
3725
4095
  onChange: (e) => onChange({ showHeader: e.target.checked }),
3726
4096
  children: "\u663E\u793A\u8868\u5934"
3727
4097
  }
4098
+ ) }),
4099
+ TABLE_ROW_FIELDS.map(([key, label, fallback]) => /* @__PURE__ */ jsxs(
4100
+ "label",
4101
+ {
4102
+ className: "cc-print-design-column-half",
4103
+ "data-tour-field": key,
4104
+ children: [
4105
+ label,
4106
+ /* @__PURE__ */ jsx(
4107
+ ReactInputNumber,
4108
+ {
4109
+ min: toDisplayUnit(
4110
+ key === "fontSize" ? fromDisplayUnit(1, "pt") : 1,
4111
+ displayUnit
4112
+ ),
4113
+ step: 0.1,
4114
+ value: toDisplayUnit(
4115
+ key === "fontSize" ? fromDisplayUnit(element[key] ?? fallback, "pt") : element[key] ?? fallback,
4116
+ displayUnit
4117
+ ),
4118
+ onChange: (value) => {
4119
+ if (value != null && Number.isFinite(value) && value > 0)
4120
+ onChange({
4121
+ [key]: key === "fontSize" ? toDisplayUnit(fromDisplayUnit(value, displayUnit), "pt") : fromDisplayUnit(value, displayUnit)
4122
+ });
4123
+ }
4124
+ }
4125
+ )
4126
+ ]
4127
+ },
4128
+ key
4129
+ )),
4130
+ /* @__PURE__ */ jsxs(
4131
+ "label",
4132
+ {
4133
+ className: "cc-print-design-column-half",
4134
+ "data-tour-field": "printRowCount",
4135
+ children: [
4136
+ "\u6BCF\u9875\u884C\u6570\uFF080 \u4E0D\u9650\uFF09",
4137
+ /* @__PURE__ */ jsx(
4138
+ ReactInputNumber,
4139
+ {
4140
+ "aria-label": "\u6BCF\u9875\u884C\u6570",
4141
+ min: 0,
4142
+ precision: 0,
4143
+ value: element.printRowCount ?? 0,
4144
+ onChange: (value) => {
4145
+ if (value != null && Number.isFinite(value))
4146
+ onChange(resizeTableRowCount(element, value));
4147
+ }
4148
+ }
4149
+ )
4150
+ ]
4151
+ }
3728
4152
  ),
3729
- TABLE_ROW_FIELDS.map(([key, label, fallback]) => /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
3730
- label,
3731
- /* @__PURE__ */ jsx(
3732
- ReactInputNumber,
3733
- {
3734
- min: toDisplayUnit(
3735
- key === "fontSize" ? fromDisplayUnit(1, "pt") : 1,
3736
- displayUnit
3737
- ),
3738
- step: 0.1,
3739
- value: toDisplayUnit(
3740
- key === "fontSize" ? fromDisplayUnit(element[key] ?? fallback, "pt") : element[key] ?? fallback,
3741
- displayUnit
3742
- ),
3743
- onChange: (value) => {
3744
- if (value != null && Number.isFinite(value) && value > 0)
3745
- onChange({
3746
- [key]: key === "fontSize" ? toDisplayUnit(fromDisplayUnit(value, displayUnit), "pt") : fromDisplayUnit(value, displayUnit)
3747
- });
3748
- }
3749
- }
3750
- )
3751
- ] }, key)),
3752
- /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
3753
- "\u6BCF\u9875\u884C\u6570\uFF080 \u4E0D\u9650\uFF09",
3754
- /* @__PURE__ */ jsx(
3755
- ReactInputNumber,
3756
- {
3757
- "aria-label": "\u6BCF\u9875\u884C\u6570",
3758
- min: 0,
3759
- precision: 0,
3760
- value: element.printRowCount ?? 0,
3761
- onChange: (value) => {
3762
- if (value != null && Number.isFinite(value))
3763
- onChange(resizeTableRowCount(element, value));
3764
- }
3765
- }
3766
- )
3767
- ] }),
3768
4153
  /* @__PURE__ */ jsx(
3769
4154
  ReactButton,
3770
4155
  {
@@ -3823,38 +4208,46 @@ function TableJsonField({
3823
4208
  setDraft(JSON.stringify(value, null, 2));
3824
4209
  setError("");
3825
4210
  }, [value]);
3826
- return /* @__PURE__ */ jsxs(ReactCollapsePanel, { className: "cc-print-design-table-json", title: label, children: [
3827
- /* @__PURE__ */ jsx(
3828
- ReactTextArea,
3829
- {
3830
- className: "canvas-react-scrollbar",
3831
- "aria-label": label,
3832
- value: draft,
3833
- onChange: (e) => setDraft(e.target.value)
3834
- }
3835
- ),
3836
- error ? /* @__PURE__ */ jsx("p", { role: "alert", children: error }) : null,
3837
- /* @__PURE__ */ jsxs(
3838
- ReactButton,
3839
- {
3840
- onClick: () => {
3841
- try {
3842
- const next = JSON.parse(draft);
3843
- if (!validate(next))
3844
- throw new Error("\u683C\u5F0F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u6570\u7EC4\u53CA\u5B57\u6BB5\u7C7B\u578B\u3002");
3845
- onChange(next);
3846
- setError("");
3847
- } catch (error2) {
3848
- setError(error2 instanceof Error ? error2.message : "JSON \u683C\u5F0F\u65E0\u6548");
4211
+ return /* @__PURE__ */ jsxs(
4212
+ ReactCollapsePanel,
4213
+ {
4214
+ className: "cc-print-design-table-json",
4215
+ title: label,
4216
+ "data-tour-field": label === "\u5217\u914D\u7F6E JSON" ? "columns" : label === "\u9759\u6001\u6570\u636E JSON" || label === "\u9ED8\u8BA4\u6570\u636E JSON" ? "dataSource" : void 0,
4217
+ children: [
4218
+ /* @__PURE__ */ jsx(
4219
+ ReactTextArea,
4220
+ {
4221
+ className: "canvas-react-scrollbar",
4222
+ "aria-label": label,
4223
+ value: draft,
4224
+ onChange: (e) => setDraft(e.target.value)
3849
4225
  }
3850
- },
3851
- children: [
3852
- "\u5E94\u7528",
3853
- label
3854
- ]
3855
- }
3856
- )
3857
- ] });
4226
+ ),
4227
+ error ? /* @__PURE__ */ jsx("p", { role: "alert", children: error }) : null,
4228
+ /* @__PURE__ */ jsxs(
4229
+ ReactButton,
4230
+ {
4231
+ onClick: () => {
4232
+ try {
4233
+ const next = JSON.parse(draft);
4234
+ if (!validate(next))
4235
+ throw new Error("\u683C\u5F0F\u65E0\u6548\uFF0C\u8BF7\u68C0\u67E5\u6570\u7EC4\u53CA\u5B57\u6BB5\u7C7B\u578B\u3002");
4236
+ onChange(next);
4237
+ setError("");
4238
+ } catch (error2) {
4239
+ setError(error2 instanceof Error ? error2.message : "JSON \u683C\u5F0F\u65E0\u6548");
4240
+ }
4241
+ },
4242
+ children: [
4243
+ "\u5E94\u7528",
4244
+ label
4245
+ ]
4246
+ }
4247
+ )
4248
+ ]
4249
+ }
4250
+ );
3858
4251
  }
3859
4252
  function TableRowsPanel({
3860
4253
  rows,
@@ -3989,7 +4382,7 @@ function TableBindingPanel({
3989
4382
  const source = resolveTableDataSource(data, element.dataPath);
3990
4383
  const rows = resolveTableRows(element, data);
3991
4384
  return /* @__PURE__ */ jsxs("div", { children: [
3992
- /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", children: [
4385
+ /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", "data-tour-field": "dataPath", children: [
3993
4386
  /* @__PURE__ */ jsx("span", { children: "\u8868\u683C\u6570\u636E\u6E90\u8DEF\u5F84" }),
3994
4387
  /* @__PURE__ */ jsx(
3995
4388
  DataPathPicker,
@@ -4029,13 +4422,13 @@ function TableDataPanel({
4029
4422
  title: "\u6570\u636E",
4030
4423
  defaultOpen: true,
4031
4424
  children: [
4032
- /* @__PURE__ */ jsx(
4425
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "dataMode", children: /* @__PURE__ */ jsx(
4033
4426
  DataModeButtons,
4034
4427
  {
4035
4428
  value: element.dataMode ?? "static",
4036
4429
  onChange: (mode) => onChange({ dataMode: mode })
4037
4430
  }
4038
- ),
4431
+ ) }),
4039
4432
  element.dataMode === "binding" ? /* @__PURE__ */ jsxs(Fragment, { children: [
4040
4433
  /* @__PURE__ */ jsx(
4041
4434
  TableBindingPanel,
@@ -4046,14 +4439,14 @@ function TableDataPanel({
4046
4439
  onChange
4047
4440
  }
4048
4441
  ),
4049
- /* @__PURE__ */ jsx(
4442
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "fallbackToStatic", children: /* @__PURE__ */ jsx(
4050
4443
  ReactCheckbox,
4051
4444
  {
4052
4445
  checked: element.fallbackToStatic ?? false,
4053
4446
  onChange: (event) => onChange({ fallbackToStatic: event.target.checked }),
4054
4447
  children: "\u6570\u636E\u6E90\u7F3A\u5931\u65F6\u4F7F\u7528\u9ED8\u8BA4\u5185\u5BB9"
4055
4448
  }
4056
- ),
4449
+ ) }),
4057
4450
  element.fallbackToStatic && /* @__PURE__ */ jsxs(ReactCollapsePanel, { title: "\u9ED8\u8BA4\u5185\u5BB9", defaultOpen: true, children: [
4058
4451
  /* @__PURE__ */ jsx(
4059
4452
  TableRowsPanel,
@@ -4099,6 +4492,7 @@ function TableDataPanel({
4099
4492
  function TableLayoutPanel({
4100
4493
  element,
4101
4494
  onChange,
4495
+ samples = [],
4102
4496
  showGrandTotalOption = false
4103
4497
  }) {
4104
4498
  const { displayUnit } = useEditorPreferences();
@@ -4110,7 +4504,36 @@ function TableLayoutPanel({
4110
4504
  className: "cc-print-design-property-section",
4111
4505
  contentClassName: "cc-print-design-table-data cc-print-design-compact-grid",
4112
4506
  children: [
4113
- /* @__PURE__ */ jsxs("label", { children: [
4507
+ /* @__PURE__ */ jsxs("label", { "data-tour-field": "borderMode", children: [
4508
+ "\u6253\u5370\u8FB9\u6846",
4509
+ /* @__PURE__ */ jsx(
4510
+ ReactSelect,
4511
+ {
4512
+ value: element.borderMode ?? "show",
4513
+ options: [
4514
+ { label: "\u663E\u793A", value: "show" },
4515
+ { label: "\u9690\u85CF", value: "hide" },
4516
+ { label: "\u52A8\u6001\u6570\u636E", value: "binding" }
4517
+ ],
4518
+ onChange: (value) => onChange({
4519
+ borderMode: value
4520
+ })
4521
+ }
4522
+ )
4523
+ ] }),
4524
+ element.borderMode === "binding" && /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", "data-tour-field": "borderPath", children: [
4525
+ /* @__PURE__ */ jsx("span", { children: "\u8FB9\u6846\u6570\u636E\u5B57\u6BB5" }),
4526
+ /* @__PURE__ */ jsx(
4527
+ DataPathPicker,
4528
+ {
4529
+ label: "\u8FB9\u6846\u6570\u636E\u5B57\u6BB5",
4530
+ value: element.borderPath ?? "",
4531
+ samples,
4532
+ onChange: (borderPath) => onChange({ borderPath })
4533
+ }
4534
+ )
4535
+ ] }),
4536
+ /* @__PURE__ */ jsxs("label", { "data-tour-field": "cellBorder", children: [
4114
4537
  "\u8FB9\u6846\u5BBD\u5EA6",
4115
4538
  /* @__PURE__ */ jsx(
4116
4539
  ReactInputNumber,
@@ -4166,45 +4589,434 @@ function TableLayoutPanel({
4166
4589
  contentClassName: "cc-print-design-table-data",
4167
4590
  children: [
4168
4591
  /* @__PURE__ */ jsx(
4169
- ReactCheckbox,
4592
+ ReactCheckbox,
4593
+ {
4594
+ checked: element.showSummary !== false,
4595
+ onChange: (event) => onChange({ showSummary: event.target.checked }),
4596
+ children: "\u663E\u793A\u6C47\u603B\u884C"
4597
+ }
4598
+ ),
4599
+ /* @__PURE__ */ jsxs("label", { children: [
4600
+ "\u6C47\u603B\u884C\u9AD8",
4601
+ /* @__PURE__ */ jsx(
4602
+ ReactInputNumber,
4603
+ {
4604
+ "aria-label": "\u6C47\u603B\u884C\u9AD8",
4605
+ min: toDisplayUnit(1, displayUnit),
4606
+ value: toDisplayUnit(
4607
+ element.summaryRowHeight ?? element.rowHeight ?? 8,
4608
+ displayUnit
4609
+ ),
4610
+ onChange: (value) => {
4611
+ if (value != null && Number.isFinite(value) && value > 0)
4612
+ onChange({
4613
+ summaryRowHeight: fromDisplayUnit(value, displayUnit)
4614
+ });
4615
+ }
4616
+ }
4617
+ )
4618
+ ] }),
4619
+ showGrandTotalOption ? /* @__PURE__ */ jsx(
4620
+ ReactCheckbox,
4621
+ {
4622
+ checked: element.showGrandTotal ?? true,
4623
+ onChange: (event) => onChange({ showGrandTotal: event.target.checked }),
4624
+ children: "\u663E\u793A\u603B\u8BA1\u5217"
4625
+ }
4626
+ ) : null
4627
+ ]
4628
+ }
4629
+ )
4630
+ ] });
4631
+ }
4632
+ function TableCellLayoutPanel({
4633
+ element,
4634
+ onChange
4635
+ }) {
4636
+ const { displayUnit } = useEditorPreferences();
4637
+ return /* @__PURE__ */ jsxs(
4638
+ ReactCollapsePanel,
4639
+ {
4640
+ title: "\u7EDF\u4E00\u5355\u5143\u683C\u5E03\u5C40",
4641
+ className: "cc-print-design-property-section",
4642
+ contentClassName: "cc-print-design-column-grid",
4643
+ children: [
4644
+ /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
4645
+ "\u6C34\u5E73\u5BF9\u9F50",
4646
+ /* @__PURE__ */ jsx(
4647
+ ReactSelect,
4648
+ {
4649
+ value: element.cellAlign ?? "left",
4650
+ options: TABLE_ALIGN_OPTIONS,
4651
+ onChange: (value) => onChange({
4652
+ cellAlign: value
4653
+ })
4654
+ }
4655
+ )
4656
+ ] }),
4657
+ /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
4658
+ "\u5782\u76F4\u5BF9\u9F50",
4659
+ /* @__PURE__ */ jsx(
4660
+ ReactSelect,
4661
+ {
4662
+ value: element.cellVerticalAlign ?? "middle",
4663
+ options: TABLE_VERTICAL_ALIGN_OPTIONS,
4664
+ onChange: (value) => onChange({
4665
+ cellVerticalAlign: value
4666
+ })
4667
+ }
4668
+ )
4669
+ ] }),
4670
+ /* @__PURE__ */ jsxs("label", { children: [
4671
+ "\u5185\u5BB9\u8D85\u51FA",
4672
+ /* @__PURE__ */ jsx(
4673
+ ReactSelect,
4674
+ {
4675
+ value: element.cellOverflow ?? "wrap",
4676
+ options: TABLE_OVERFLOW_OPTIONS,
4677
+ onChange: (value) => onChange({
4678
+ cellOverflow: value
4679
+ })
4680
+ }
4681
+ )
4682
+ ] }),
4683
+ ["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
4684
+ { top: "\u4E0A", right: "\u53F3", bottom: "\u4E0B", left: "\u5DE6" }[side],
4685
+ "\u5185\u8FB9\u8DDD",
4686
+ /* @__PURE__ */ jsx(
4687
+ ReactInputNumber,
4688
+ {
4689
+ min: 0,
4690
+ step: 0.1,
4691
+ value: toDisplayUnit(
4692
+ fromDisplayUnit(
4693
+ element.cellPadding?.[side] ?? (side === "left" || side === "right" ? 4 : 0),
4694
+ "px"
4695
+ ),
4696
+ displayUnit
4697
+ ),
4698
+ onChange: (value) => {
4699
+ if (value != null && Number.isFinite(value) && value >= 0)
4700
+ onChange({
4701
+ cellPadding: {
4702
+ ...element.cellPadding,
4703
+ [side]: toDisplayUnit(
4704
+ fromDisplayUnit(value, displayUnit),
4705
+ "px"
4706
+ )
4707
+ }
4708
+ });
4709
+ }
4710
+ }
4711
+ )
4712
+ ] }, side))
4713
+ ]
4714
+ }
4715
+ );
4716
+ }
4717
+ function TableCellsPanel({
4718
+ element,
4719
+ data,
4720
+ samples = [],
4721
+ tableCellSelection,
4722
+ onMergeSelectedTableCells,
4723
+ onChange
4724
+ }) {
4725
+ const [row, setRow] = useState(1);
4726
+ const [column, setColumn] = useState(1);
4727
+ const rows = resolveTableRows(element, data);
4728
+ const rowCount = Math.max(rows.length, element.printRowCount ?? 0, 1);
4729
+ const columnCount = Math.max(
4730
+ tableLeafColumns(element.columns.filter((item) => !item.hidden)).filter(
4731
+ (item) => !item.hidden
4732
+ ).length,
4733
+ 1
4734
+ );
4735
+ const rowIndex = Math.min(Math.max(row - 1, 0), rowCount - 1);
4736
+ const columnIndex = Math.min(Math.max(column - 1, 0), columnCount - 1);
4737
+ const cell = element.cells?.find(
4738
+ (item) => item.rowIndex === rowIndex && item.columnIndex === columnIndex
4739
+ );
4740
+ const update = (patch) => {
4741
+ const next = { rowIndex, columnIndex, ...cell, ...patch };
4742
+ const rowSpan = Math.max(1, next.rowSpan ?? 1);
4743
+ const colSpan = Math.max(1, next.colSpan ?? 1);
4744
+ if ((rowSpan > 1 || colSpan > 1) && element.cells?.some(
4745
+ (item) => (item.rowIndex !== rowIndex || item.columnIndex !== columnIndex) && ((item.rowSpan ?? 1) > 1 || (item.colSpan ?? 1) > 1) && rowIndex < item.rowIndex + Math.max(1, item.rowSpan ?? 1) && rowIndex + rowSpan > item.rowIndex && columnIndex < item.columnIndex + Math.max(1, item.colSpan ?? 1) && columnIndex + colSpan > item.columnIndex
4746
+ ))
4747
+ return;
4748
+ onChange({
4749
+ cells: [
4750
+ ...(element.cells ?? []).filter(
4751
+ (item) => item.rowIndex !== rowIndex || item.columnIndex !== columnIndex
4752
+ ),
4753
+ next
4754
+ ]
4755
+ });
4756
+ };
4757
+ const merged = (cell?.rowSpan ?? 1) > 1 || (cell?.colSpan ?? 1) > 1;
4758
+ const selected = tableCellSelection?.elementId === element.id ? tableCellSelection : null;
4759
+ const canMergeSelection = !!selected && !selected.selectorKind && (selected.startRow !== selected.endRow || selected.startColumn !== selected.endColumn);
4760
+ return /* @__PURE__ */ jsxs(
4761
+ ReactCollapsePanel,
4762
+ {
4763
+ title: "\u5355\u5143\u683C",
4764
+ className: "cc-print-design-property-section",
4765
+ contentClassName: "cc-print-design-table-data cc-print-design-compact-grid",
4766
+ children: [
4767
+ /* @__PURE__ */ jsx(
4768
+ ReactButton,
4769
+ {
4770
+ disabled: !canMergeSelection || !onMergeSelectedTableCells,
4771
+ onClick: onMergeSelectedTableCells,
4772
+ children: "\u5408\u5E76\u9009\u4E2D\u5355\u5143\u683C"
4773
+ }
4774
+ ),
4775
+ /* @__PURE__ */ jsxs("label", { children: [
4776
+ "\u884C",
4777
+ /* @__PURE__ */ jsx(
4778
+ ReactInputNumber,
4779
+ {
4780
+ min: 1,
4781
+ max: rowCount,
4782
+ precision: 0,
4783
+ value: row,
4784
+ onChange: (value) => {
4785
+ if (value != null)
4786
+ setRow(Math.min(rowCount, Math.max(1, Math.round(value))));
4787
+ }
4788
+ }
4789
+ )
4790
+ ] }),
4791
+ /* @__PURE__ */ jsxs("label", { children: [
4792
+ "\u5217",
4793
+ /* @__PURE__ */ jsx(
4794
+ ReactInputNumber,
4795
+ {
4796
+ min: 1,
4797
+ max: columnCount,
4798
+ precision: 0,
4799
+ value: column,
4800
+ onChange: (value) => {
4801
+ if (value != null)
4802
+ setColumn(Math.min(columnCount, Math.max(1, Math.round(value))));
4803
+ }
4804
+ }
4805
+ )
4806
+ ] }),
4807
+ /* @__PURE__ */ jsxs("label", { children: [
4808
+ "\u5408\u5E76\u884C\u6570",
4809
+ /* @__PURE__ */ jsx(
4810
+ ReactInputNumber,
4811
+ {
4812
+ min: 1,
4813
+ max: rowCount - rowIndex,
4814
+ precision: 0,
4815
+ value: cell?.rowSpan ?? 1,
4816
+ onChange: (value) => {
4817
+ if (value != null)
4818
+ update({
4819
+ rowSpan: Math.min(
4820
+ rowCount - rowIndex,
4821
+ Math.max(1, Math.round(value))
4822
+ )
4823
+ });
4824
+ }
4825
+ }
4826
+ )
4827
+ ] }),
4828
+ /* @__PURE__ */ jsxs("label", { children: [
4829
+ "\u5408\u5E76\u5217\u6570",
4830
+ /* @__PURE__ */ jsx(
4831
+ ReactInputNumber,
4832
+ {
4833
+ min: 1,
4834
+ max: columnCount - columnIndex,
4835
+ precision: 0,
4836
+ value: cell?.colSpan ?? 1,
4837
+ onChange: (value) => {
4838
+ if (value != null)
4839
+ update({
4840
+ colSpan: Math.min(
4841
+ columnCount - columnIndex,
4842
+ Math.max(1, Math.round(value))
4843
+ )
4844
+ });
4845
+ }
4846
+ }
4847
+ )
4848
+ ] }),
4849
+ /* @__PURE__ */ jsx(
4850
+ ReactButton,
4851
+ {
4852
+ disabled: !merged,
4853
+ onClick: () => update({ rowSpan: 1, colSpan: 1 }),
4854
+ children: "\u53D6\u6D88\u5408\u5E76"
4855
+ }
4856
+ ),
4857
+ /* @__PURE__ */ jsxs("label", { children: [
4858
+ "\u5BF9\u89D2\u7EBF",
4859
+ /* @__PURE__ */ jsx(
4860
+ ReactSelect,
4861
+ {
4862
+ value: cell?.diagonal ?? "none",
4863
+ options: [
4864
+ { label: "\u65E0", value: "none" },
4865
+ { label: "\u5DE6\u4E0A\u81F3\u53F3\u4E0B", value: "down" },
4866
+ { label: "\u5DE6\u4E0B\u81F3\u53F3\u4E0A", value: "up" }
4867
+ ],
4868
+ onChange: (value) => update({
4869
+ diagonal: value === "none" ? void 0 : value
4870
+ })
4871
+ }
4872
+ )
4873
+ ] }),
4874
+ cell?.diagonal && /* @__PURE__ */ jsxs(Fragment, { children: [
4875
+ /* @__PURE__ */ jsxs("label", { children: [
4876
+ "\u8D77\u59CB\u5185\u5BB9",
4877
+ /* @__PURE__ */ jsx(
4878
+ ReactInput,
4879
+ {
4880
+ value: cell.diagonalStart ?? "",
4881
+ onChange: (event) => update({ diagonalStart: event.target.value })
4882
+ }
4883
+ )
4884
+ ] }),
4885
+ /* @__PURE__ */ jsxs("label", { children: [
4886
+ "\u7ED3\u675F\u5185\u5BB9",
4887
+ /* @__PURE__ */ jsx(
4888
+ ReactInput,
4889
+ {
4890
+ value: cell.diagonalEnd ?? "",
4891
+ onChange: (event) => update({ diagonalEnd: event.target.value })
4892
+ }
4893
+ )
4894
+ ] })
4895
+ ] }),
4896
+ /* @__PURE__ */ jsxs("label", { children: [
4897
+ "\u80CC\u666F\u989C\u8272",
4898
+ /* @__PURE__ */ jsx(
4899
+ ReactColorPicker,
4900
+ {
4901
+ value: cell?.backgroundColor ?? "#ffffff",
4902
+ onChange: (backgroundColor) => update({ backgroundColor })
4903
+ }
4904
+ )
4905
+ ] }),
4906
+ /* @__PURE__ */ jsxs("label", { children: [
4907
+ "\u6587\u5B57\u989C\u8272",
4908
+ /* @__PURE__ */ jsx(
4909
+ ReactColorPicker,
4910
+ {
4911
+ value: cell?.color ?? "#000000",
4912
+ onChange: (color) => update({ color })
4913
+ }
4914
+ )
4915
+ ] }),
4916
+ /* @__PURE__ */ jsxs("label", { children: [
4917
+ "\u8FB9\u6846\u989C\u8272",
4918
+ /* @__PURE__ */ jsx(
4919
+ ReactColorPicker,
4920
+ {
4921
+ value: cell?.borderColor ?? element.cellBorder?.color ?? "#000000",
4922
+ onChange: (borderColor) => update({ borderColor })
4923
+ }
4924
+ )
4925
+ ] }),
4926
+ /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", children: [
4927
+ /* @__PURE__ */ jsx("span", { children: "\u52A8\u6001\u8FB9\u6846\u5B57\u6BB5" }),
4928
+ /* @__PURE__ */ jsx(
4929
+ DataPathPicker,
4930
+ {
4931
+ label: "\u52A8\u6001\u8FB9\u6846\u5B57\u6BB5",
4932
+ value: cell?.borderPath ?? "",
4933
+ samples: [rows[rowIndex] ?? {}, ...samples],
4934
+ onChange: (borderPath) => update({ borderPath })
4935
+ }
4936
+ )
4937
+ ] }),
4938
+ /* @__PURE__ */ jsx(
4939
+ ReactButton,
4940
+ {
4941
+ onClick: () => update({ borderColor: "transparent", borderPath: void 0 }),
4942
+ children: "\u9690\u85CF\u6B64\u5355\u5143\u683C\u8FB9\u6846"
4943
+ }
4944
+ )
4945
+ ]
4946
+ }
4947
+ );
4948
+ }
4949
+ function TableAutoMergePanel({
4950
+ element,
4951
+ onChange
4952
+ }) {
4953
+ const [rowKeys, setRowKeys] = useState("");
4954
+ const [rowColumns, setRowColumns] = useState("");
4955
+ const [columnKeys, setColumnKeys] = useState("");
4956
+ useEffect(() => {
4957
+ setRowKeys(element.mergeCell?.row?.keys.join(", ") ?? "");
4958
+ setRowColumns(element.mergeCell?.row?.columns?.join(", ") ?? "");
4959
+ setColumnKeys(element.mergeCell?.column?.keys.join(", ") ?? "");
4960
+ }, [element.mergeCell]);
4961
+ const fields = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
4962
+ const apply = (nextRows, nextColumns, nextColumnKeys) => {
4963
+ const keys = fields(nextRows);
4964
+ const columns = fields(nextColumns);
4965
+ const horizontal = fields(nextColumnKeys);
4966
+ const mergeCell = {
4967
+ row: keys.length ? { keys, columns: columns.length ? columns : void 0 } : void 0,
4968
+ column: horizontal.length ? { keys: horizontal } : void 0
4969
+ };
4970
+ onChange({
4971
+ mergeCell: mergeCell.row || mergeCell.column ? mergeCell : void 0
4972
+ });
4973
+ };
4974
+ return /* @__PURE__ */ jsxs(
4975
+ ReactCollapsePanel,
4976
+ {
4977
+ title: "\u6570\u636E\u81EA\u52A8\u5408\u5E76",
4978
+ className: "cc-print-design-property-section",
4979
+ contentClassName: "cc-print-design-table-data cc-print-design-compact-grid",
4980
+ children: [
4981
+ /* @__PURE__ */ jsxs("label", { "data-tour-field": "mergeCell", children: [
4982
+ "\u8FDE\u7EED\u884C\u5206\u7EC4\u5B57\u6BB5",
4983
+ /* @__PURE__ */ jsx(
4984
+ ReactInput,
4170
4985
  {
4171
- checked: element.showSummary !== false,
4172
- onChange: (event) => onChange({ showSummary: event.target.checked }),
4173
- children: "\u663E\u793A\u6C47\u603B\u884C"
4986
+ value: rowKeys,
4987
+ placeholder: "\u4F8B\u5982\uFF1A\u8BA2\u5355\u7C7B\u578B, \u9879\u76EE",
4988
+ onChange: (event) => setRowKeys(event.target.value),
4989
+ onBlur: () => apply(rowKeys, rowColumns, columnKeys)
4174
4990
  }
4175
- ),
4176
- /* @__PURE__ */ jsxs("label", { children: [
4177
- "\u6C47\u603B\u884C\u9AD8",
4178
- /* @__PURE__ */ jsx(
4179
- ReactInputNumber,
4180
- {
4181
- "aria-label": "\u6C47\u603B\u884C\u9AD8",
4182
- min: toDisplayUnit(1, displayUnit),
4183
- value: toDisplayUnit(
4184
- element.summaryRowHeight ?? element.rowHeight ?? 8,
4185
- displayUnit
4186
- ),
4187
- onChange: (value) => {
4188
- if (value != null && Number.isFinite(value) && value > 0)
4189
- onChange({
4190
- summaryRowHeight: fromDisplayUnit(value, displayUnit)
4191
- });
4192
- }
4193
- }
4194
- )
4195
- ] }),
4196
- showGrandTotalOption ? /* @__PURE__ */ jsx(
4197
- ReactCheckbox,
4991
+ )
4992
+ ] }),
4993
+ /* @__PURE__ */ jsxs("label", { children: [
4994
+ "\u6267\u884C\u884C\u5408\u5E76\u7684\u5217",
4995
+ /* @__PURE__ */ jsx(
4996
+ ReactInput,
4198
4997
  {
4199
- checked: element.showGrandTotal ?? true,
4200
- onChange: (event) => onChange({ showGrandTotal: event.target.checked }),
4201
- children: "\u663E\u793A\u603B\u8BA1\u5217"
4998
+ value: rowColumns,
4999
+ placeholder: "\u7559\u7A7A\u65F6\u4F7F\u7528\u5206\u7EC4\u5B57\u6BB5",
5000
+ onChange: (event) => setRowColumns(event.target.value),
5001
+ onBlur: () => apply(rowKeys, rowColumns, columnKeys)
4202
5002
  }
4203
- ) : null
4204
- ]
4205
- }
4206
- )
4207
- ] });
5003
+ )
5004
+ ] }),
5005
+ /* @__PURE__ */ jsxs("label", { children: [
5006
+ "\u540C\u884C\u76F8\u90BB\u5217\u5408\u5E76\u5B57\u6BB5",
5007
+ /* @__PURE__ */ jsx(
5008
+ ReactInput,
5009
+ {
5010
+ value: columnKeys,
5011
+ placeholder: "\u4F8B\u5982\uFF1A\u5206\u7C7B, \u5907\u6CE8",
5012
+ onChange: (event) => setColumnKeys(event.target.value),
5013
+ onBlur: () => apply(rowKeys, rowColumns, columnKeys)
5014
+ }
5015
+ )
5016
+ ] })
5017
+ ]
5018
+ }
5019
+ );
4208
5020
  }
4209
5021
  function TableColorsPanel({
4210
5022
  colors,
@@ -4348,6 +5160,24 @@ function TableColumnsPanel({
4348
5160
  title: "\u5355\u5143\u683C\u5E03\u5C40",
4349
5161
  contentClassName: "cc-print-design-column-grid",
4350
5162
  children: [
5163
+ /* @__PURE__ */ jsx(
5164
+ ReactButton,
5165
+ {
5166
+ type: "text",
5167
+ onClick: () => update(index, {
5168
+ align: void 0,
5169
+ cellOverflow: void 0,
5170
+ ellipsis: void 0,
5171
+ cellPadding: void 0,
5172
+ cellStyle: column.cellStyle ? {
5173
+ ...column.cellStyle,
5174
+ textAlign: void 0,
5175
+ verticalAlign: void 0
5176
+ } : void 0
5177
+ }),
5178
+ children: "\u6062\u590D\u8868\u683C\u7EDF\u4E00\u5E03\u5C40"
5179
+ }
5180
+ ),
4351
5181
  /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
4352
5182
  "\u6C34\u5E73\u5BF9\u9F50",
4353
5183
  /* @__PURE__ */ jsx(
@@ -4382,14 +5212,44 @@ function TableColumnsPanel({
4382
5212
  /* @__PURE__ */ jsx(
4383
5213
  ReactSelect,
4384
5214
  {
4385
- value: column.ellipsis == null ? layoutDefaults?.cellOverflow ?? "wrap" : column.ellipsis ? "ellipsis" : "wrap",
5215
+ value: column.cellOverflow ?? (column.ellipsis == null ? layoutDefaults?.cellOverflow ?? "wrap" : column.ellipsis ? "ellipsis" : "wrap"),
4386
5216
  options: TABLE_OVERFLOW_OPTIONS,
4387
5217
  onChange: (value) => update(index, {
4388
- ellipsis: value === "ellipsis"
5218
+ cellOverflow: value
4389
5219
  })
4390
5220
  }
4391
5221
  )
4392
- ] })
5222
+ ] }),
5223
+ ["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */ jsxs("label", { className: "cc-print-design-column-half", children: [
5224
+ { top: "\u4E0A", right: "\u53F3", bottom: "\u4E0B", left: "\u5DE6" }[side],
5225
+ "\u5185\u8FB9\u8DDD",
5226
+ /* @__PURE__ */ jsx(
5227
+ ReactInputNumber,
5228
+ {
5229
+ min: 0,
5230
+ step: 0.1,
5231
+ value: toDisplayUnit(
5232
+ fromDisplayUnit(
5233
+ column.cellPadding?.[side] ?? layoutDefaults?.cellPadding?.[side] ?? (side === "left" || side === "right" ? 4 : 0),
5234
+ "px"
5235
+ ),
5236
+ displayUnit
5237
+ ),
5238
+ onChange: (value) => {
5239
+ if (value != null && Number.isFinite(value) && value >= 0)
5240
+ update(index, {
5241
+ cellPadding: {
5242
+ ...column.cellPadding,
5243
+ [side]: toDisplayUnit(
5244
+ fromDisplayUnit(value, displayUnit),
5245
+ "px"
5246
+ )
5247
+ }
5248
+ });
5249
+ }
5250
+ }
5251
+ )
5252
+ ] }, side))
4393
5253
  ]
4394
5254
  }
4395
5255
  ),
@@ -4500,8 +5360,14 @@ function TablePropertiesPanel({
4500
5360
  page,
4501
5361
  data,
4502
5362
  samples,
5363
+ tableCellSelection,
5364
+ onMergeSelectedTableCells,
4503
5365
  onChange
4504
5366
  }) {
5367
+ const borderSamples = [
5368
+ ...samples ?? [data ?? {}],
5369
+ ...resolveTableRows(element, data).slice(0, 100)
5370
+ ];
4505
5371
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4506
5372
  /* @__PURE__ */ jsx(
4507
5373
  TableRowSettingsPanel,
@@ -4511,7 +5377,27 @@ function TablePropertiesPanel({
4511
5377
  onChange
4512
5378
  }
4513
5379
  ),
4514
- /* @__PURE__ */ jsx(TableLayoutPanel, { element, onChange }),
5380
+ /* @__PURE__ */ jsx(
5381
+ TableLayoutPanel,
5382
+ {
5383
+ element,
5384
+ samples: borderSamples,
5385
+ onChange
5386
+ }
5387
+ ),
5388
+ /* @__PURE__ */ jsx(TableCellLayoutPanel, { element, onChange }),
5389
+ /* @__PURE__ */ jsx(
5390
+ TableCellsPanel,
5391
+ {
5392
+ element,
5393
+ data,
5394
+ samples: borderSamples,
5395
+ tableCellSelection,
5396
+ onMergeSelectedTableCells,
5397
+ onChange
5398
+ }
5399
+ ),
5400
+ /* @__PURE__ */ jsx(TableAutoMergePanel, { element, onChange }),
4515
5401
  /* @__PURE__ */ jsx(
4516
5402
  ReactCollapsePanel,
4517
5403
  {
@@ -5073,15 +5959,15 @@ function PivotTablePropertiesPanel({
5073
5959
  defaultOpen: true,
5074
5960
  className: "cc-print-design-property-section",
5075
5961
  children: /* @__PURE__ */ jsxs("div", { className: "cc-print-design-table-data cc-print-design-data-compact", children: [
5076
- /* @__PURE__ */ jsx(
5962
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "dataMode", children: /* @__PURE__ */ jsx(
5077
5963
  DataModeButtons,
5078
5964
  {
5079
5965
  value: element.dataMode ?? "static",
5080
5966
  onChange: (dataMode) => onChange({ dataMode })
5081
5967
  }
5082
- ),
5968
+ ) }),
5083
5969
  element.dataMode === "binding" ? /* @__PURE__ */ jsxs(Fragment, { children: [
5084
- /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", children: [
5970
+ /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", "data-tour-field": "dataPath", children: [
5085
5971
  /* @__PURE__ */ jsx("span", { children: "ListTable \u6570\u636E\u6E90\u8DEF\u5F84" }),
5086
5972
  /* @__PURE__ */ jsx(
5087
5973
  DataPathPicker,
@@ -5269,6 +6155,7 @@ function PivotTablePropertiesPanel({
5269
6155
  showSummary: element.showSummary ?? element.showGrandTotal ?? true
5270
6156
  },
5271
6157
  onChange,
6158
+ samples: samples ?? [data],
5272
6159
  showGrandTotalOption: true
5273
6160
  }
5274
6161
  ),
@@ -5614,6 +6501,7 @@ function BorderFields({
5614
6501
  min: 0,
5615
6502
  max: toDisplayUnit(fromDisplayUnit(10, "px"), displayUnit),
5616
6503
  step: displayUnit === "in" ? 1e-3 : 0.01,
6504
+ precision: displayUnit === "in" ? 3 : 2,
5617
6505
  value: toDisplayUnit(
5618
6506
  fromDisplayUnit(value?.width ?? 1, "px"),
5619
6507
  displayUnit
@@ -5670,16 +6558,16 @@ function GanttPropertiesPanel({
5670
6558
  className: "cc-print-design-property-section",
5671
6559
  children: [
5672
6560
  /* @__PURE__ */ jsxs("div", { className: "cc-print-design-table-data cc-print-design-data-compact", children: [
5673
- /* @__PURE__ */ jsx(
6561
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "dataMode", children: /* @__PURE__ */ jsx(
5674
6562
  DataModeButtons,
5675
6563
  {
5676
6564
  label: "\u4EFB\u52A1\u6570\u636E\u65B9\u5F0F",
5677
6565
  value: element.dataMode ?? "static",
5678
6566
  onChange: (dataMode) => onChange({ dataMode })
5679
6567
  }
5680
- ),
6568
+ ) }),
5681
6569
  element.dataMode === "binding" ? /* @__PURE__ */ jsxs(Fragment, { children: [
5682
- /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", children: [
6570
+ /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", "data-tour-field": "dataPath", children: [
5683
6571
  /* @__PURE__ */ jsx("span", { children: "\u4EFB\u52A1\u6570\u7EC4\u8DEF\u5F84" }),
5684
6572
  /* @__PURE__ */ jsx(
5685
6573
  DataPathPicker,
@@ -5753,6 +6641,7 @@ function GanttPropertiesPanel({
5753
6641
  min: 0,
5754
6642
  max: toDisplayUnit(fromDisplayUnit(10, "px"), displayUnit),
5755
6643
  step: displayUnit === "in" ? 1e-3 : 0.01,
6644
+ precision: displayUnit === "in" ? 3 : 2,
5756
6645
  value: toDisplayUnit(
5757
6646
  fromDisplayUnit(element.dependencyLineWidth ?? 1, "px"),
5758
6647
  displayUnit
@@ -6123,6 +7012,8 @@ function ElementDataPanel(props) {
6123
7012
  element,
6124
7013
  data,
6125
7014
  samples: props.samples,
7015
+ tableCellSelection: props.tableCellSelection,
7016
+ onMergeSelectedTableCells: props.onMergeSelectedTableCells,
6126
7017
  onChange
6127
7018
  }
6128
7019
  )
@@ -6136,14 +7027,14 @@ function ElementDataPanel(props) {
6136
7027
  defaultOpen: true,
6137
7028
  className: "cc-print-design-property-section",
6138
7029
  children: /* @__PURE__ */ jsxs("div", { className: "cc-print-design-property-grid", children: [
6139
- /* @__PURE__ */ jsx(
7030
+ /* @__PURE__ */ jsx("div", { "data-tour-field": "dataConfig.mode", children: /* @__PURE__ */ jsx(
6140
7031
  DataModeButtons,
6141
7032
  {
6142
7033
  value: config.mode,
6143
7034
  disabled: props.readonly,
6144
7035
  onChange: (mode) => onChange({ dataConfig: { ...config, mode } })
6145
7036
  }
6146
- ),
7037
+ ) }),
6147
7038
  getPrintDesignDataFields(element.type).map((field) => {
6148
7039
  if (element.type === "shape" && config.mode === "static") return null;
6149
7040
  const value = element[field.key] ?? field.fallback;
@@ -6166,28 +7057,36 @@ function ElementDataPanel(props) {
6166
7057
  "div",
6167
7058
  {
6168
7059
  className: "cc-print-design-field cc-print-design-field-full",
7060
+ "data-tour-field": field.key,
6169
7061
  children: [
6170
- config.mode === "binding" && /* @__PURE__ */ jsxs("div", { className: "cc-print-design-field", children: [
6171
- /* @__PURE__ */ jsxs("span", { children: [
6172
- field.label,
6173
- " \xB7 \u5B57\u6BB5\u8DEF\u5F84"
6174
- ] }),
6175
- /* @__PURE__ */ jsx(
6176
- DataPathPicker,
6177
- {
6178
- label: `${field.label}\u7ED1\u5B9A\u8DEF\u5F84`,
6179
- disabled: props.readonly,
6180
- value: path,
6181
- samples: props.samples ?? [data],
6182
- onChange: (path2) => onChange({
6183
- dataConfig: {
6184
- ...config,
6185
- bindings: { ...config.bindings, [field.key]: path2 }
7062
+ config.mode === "binding" && /* @__PURE__ */ jsxs(
7063
+ "div",
7064
+ {
7065
+ className: "cc-print-design-field",
7066
+ "data-tour-field": `dataConfig.bindings.${field.key}`,
7067
+ children: [
7068
+ /* @__PURE__ */ jsxs("span", { children: [
7069
+ field.label,
7070
+ " \xB7 \u5B57\u6BB5\u8DEF\u5F84"
7071
+ ] }),
7072
+ /* @__PURE__ */ jsx(
7073
+ DataPathPicker,
7074
+ {
7075
+ label: `${field.label}\u7ED1\u5B9A\u8DEF\u5F84`,
7076
+ disabled: props.readonly,
7077
+ value: path,
7078
+ samples: props.samples ?? [data],
7079
+ onChange: (path2) => onChange({
7080
+ dataConfig: {
7081
+ ...config,
7082
+ bindings: { ...config.bindings, [field.key]: path2 }
7083
+ }
7084
+ })
6186
7085
  }
6187
- })
6188
- }
6189
- )
6190
- ] }),
7086
+ )
7087
+ ]
7088
+ }
7089
+ ),
6191
7090
  /* @__PURE__ */ jsx(
6192
7091
  DataValueField,
6193
7092
  {
@@ -7450,21 +8349,28 @@ function PropertiesPanel(props) {
7450
8349
  onChange: (rotation) => props.onElementChange({ rotation })
7451
8350
  }
7452
8351
  ),
7453
- /* @__PURE__ */ jsxs("label", { className: "cc-print-design-field cc-print-design-field-full", children: [
7454
- /* @__PURE__ */ jsx("span", { children: "\u8D85\u51FA\u7EB8\u5F20" }),
7455
- /* @__PURE__ */ jsx(
7456
- ReactSelect,
7457
- {
7458
- "aria-label": "\u8D85\u51FA\u7EB8\u5F20\u5904\u7406\u65B9\u5F0F",
7459
- value: element.overflowPolicy ?? (element.type === "text" || element.type === "table" || element.type === "pivotTable" ? "split" : "nextPage"),
7460
- options: getOverflowPolicyOptions(element.type),
7461
- disabled: props.readonly,
7462
- onChange: (value) => props.onElementChange({
7463
- overflowPolicy: value
7464
- })
7465
- }
7466
- )
7467
- ] })
8352
+ /* @__PURE__ */ jsxs(
8353
+ "label",
8354
+ {
8355
+ className: "cc-print-design-field cc-print-design-field-full",
8356
+ "data-tour-field": "overflowPolicy",
8357
+ children: [
8358
+ /* @__PURE__ */ jsx("span", { children: "\u8D85\u51FA\u7EB8\u5F20" }),
8359
+ /* @__PURE__ */ jsx(
8360
+ ReactSelect,
8361
+ {
8362
+ "aria-label": "\u8D85\u51FA\u7EB8\u5F20\u5904\u7406\u65B9\u5F0F",
8363
+ value: element.overflowPolicy ?? (element.type === "text" || element.type === "table" || element.type === "pivotTable" ? "split" : "nextPage"),
8364
+ options: getOverflowPolicyOptions(element.type),
8365
+ disabled: props.readonly,
8366
+ onChange: (value) => props.onElementChange({
8367
+ overflowPolicy: value
8368
+ })
8369
+ }
8370
+ )
8371
+ ]
8372
+ }
8373
+ )
7468
8374
  ] }),
7469
8375
  element.type === "text" ? /* @__PURE__ */ jsxs(PropertySection, { title: "\u6587\u672C\u6837\u5F0F", children: [
7470
8376
  /* @__PURE__ */ jsx(
@@ -8262,6 +9168,8 @@ function PropertiesPanel(props) {
8262
9168
  data: props.data,
8263
9169
  samples: props.samples,
8264
9170
  readonly: props.readonly,
9171
+ tableCellSelection: props.tableCellSelection,
9172
+ onMergeSelectedTableCells: props.onMergeSelectedTableCells,
8265
9173
  onChange: props.onElementChange
8266
9174
  },
8267
9175
  element.id
@@ -8443,31 +9351,59 @@ function NumberField(props) {
8443
9351
  const dimensional = NUMBER_FIELD_DIMENSIONS.has(props.label);
8444
9352
  const unit = dimensional || fontSize ? displayUnit : "mm";
8445
9353
  const toInput = (value) => toDisplayUnit(fontSize ? fromDisplayUnit(value, "pt") : value, unit);
8446
- return /* @__PURE__ */ jsxs("label", { className: "cc-print-design-field", children: [
8447
- /* @__PURE__ */ jsx("span", { children: props.label }),
8448
- /* @__PURE__ */ jsx(
8449
- ReactInputNumber,
8450
- {
8451
- "aria-label": props.label,
8452
- value: toInput(props.value),
8453
- min: props.min == null ? void 0 : toInput(props.min),
8454
- max: props.max == null ? void 0 : toInput(props.max),
8455
- step: props.step ?? (fontSize ? 0.1 : 1),
8456
- precision: props.precision ?? 2,
8457
- disabled: props.disabled,
8458
- onChange: (value) => value != null && props.onChange(
8459
- fontSize ? toDisplayUnit(fromDisplayUnit(value, unit), "pt") : fromDisplayUnit(value, unit)
9354
+ return /* @__PURE__ */ jsxs(
9355
+ "label",
9356
+ {
9357
+ className: "cc-print-design-field",
9358
+ "data-tour-field": numberTourFields[props.label],
9359
+ children: [
9360
+ /* @__PURE__ */ jsx("span", { children: props.label }),
9361
+ /* @__PURE__ */ jsx(
9362
+ ReactInputNumber,
9363
+ {
9364
+ "aria-label": props.label,
9365
+ value: toInput(props.value),
9366
+ min: props.min == null ? void 0 : toInput(props.min),
9367
+ max: props.max == null ? void 0 : toInput(props.max),
9368
+ step: props.step ?? (fontSize ? 0.1 : 1),
9369
+ precision: props.precision ?? 2,
9370
+ disabled: props.disabled,
9371
+ onChange: (value) => value != null && props.onChange(
9372
+ fontSize ? toDisplayUnit(fromDisplayUnit(value, unit), "pt") : fromDisplayUnit(value, unit)
9373
+ )
9374
+ }
8460
9375
  )
8461
- }
8462
- )
8463
- ] });
9376
+ ]
9377
+ }
9378
+ );
8464
9379
  }
8465
9380
  function ColorField(props) {
8466
- return /* @__PURE__ */ jsxs("label", { className: "cc-print-design-field", children: [
8467
- /* @__PURE__ */ jsx("span", { children: props.label }),
8468
- /* @__PURE__ */ jsx(ReactColorPicker, { value: props.value, onChange: props.onChange })
8469
- ] });
9381
+ return /* @__PURE__ */ jsxs(
9382
+ "label",
9383
+ {
9384
+ className: "cc-print-design-field",
9385
+ "data-tour-field": colorTourFields[props.label],
9386
+ children: [
9387
+ /* @__PURE__ */ jsx("span", { children: props.label }),
9388
+ /* @__PURE__ */ jsx(ReactColorPicker, { value: props.value, onChange: props.onChange })
9389
+ ]
9390
+ }
9391
+ );
8470
9392
  }
9393
+ var numberTourFields = {
9394
+ X: "x",
9395
+ Y: "y",
9396
+ \u5BBD\u5EA6: "width",
9397
+ \u9AD8\u5EA6: "height",
9398
+ \u65CB\u8F6C: "rotation",
9399
+ \u5B57\u53F7: "fontSize",
9400
+ \u884C\u9AD8: "rowHeight"
9401
+ };
9402
+ var colorTourFields = {
9403
+ \u6587\u5B57\u989C\u8272: "color",
9404
+ \u586B\u5145\u989C\u8272: "fill",
9405
+ \u8FB9\u6846\u989C\u8272: "borderColor"
9406
+ };
8471
9407
  function formatTime(value) {
8472
9408
  return value ? new Date(value).toLocaleString("zh-CN") : "-";
8473
9409
  }
@@ -8695,7 +9631,7 @@ async function writePrintDesignTemplates(storeKey, versions) {
8695
9631
  }
8696
9632
 
8697
9633
  // src/style.css
8698
- styleInject('.cc-print-design-editor {\n position: relative;\n --pd-border: #e4e8ef;\n --pd-text: var(--canvas-react-color-text, #263244);\n --pd-muted: var(--canvas-react-color-text-muted, #8993a2);\n --pd-primary: #1677ff;\n --pd-background: #f7f8fa;\n --pd-surface: #fff;\n --pd-workspace: #e9edf3;\n --pd-hover: #f5f7fa;\n --pd-selected: #edf4ff;\n --pd-subtle: #fafbfd;\n --pd-icon: #4279cb;\n --pd-divider: #edf0f4;\n --pd-selected-border: #86b4ff;\n --pd-danger: #dc2626;\n --pd-brand-start: #428cff;\n --pd-brand-end: #1261d8;\n --canvas-react-shadow-focus: 0 0 0 2px color-mix(in srgb, var(--pd-primary) 18%, transparent);\n --pd-label-font-size: var(--canvas-react-font-size-label, 12px);\n --pd-primary-font-size: var(--canvas-react-font-size, 13px);\n --pd-secondary-font-size: var(--canvas-react-font-size-secondary, 11px);\n --pd-panel-header-height: 36px;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--pd-text);\n background: var(--pd-background);\n font-family:\n Inter,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n "PingFang SC",\n "Microsoft YaHei",\n sans-serif;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-editor:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n}\n.cc-print-design-toolbar {\n z-index: 2;\n display: flex;\n flex: 0 0 58px;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 0 18px;\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n}\n.cc-print-design-brand,\n.cc-print-design-brand > div,\n.cc-print-design-toolbar-group {\n display: flex;\n align-items: center;\n}\n.cc-print-design-brand {\n gap: 10px;\n min-width: 180px;\n}\n.cc-print-design-brand > div {\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n}\n.cc-print-design-brand strong {\n max-width: 170px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-brand small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-brand-mark {\n display: grid;\n width: 32px;\n height: 32px;\n place-items: center;\n border-radius: 9px;\n color: #fff;\n background:\n linear-gradient(\n 145deg,\n var(--pd-brand-start),\n var(--pd-brand-end));\n font-size: 16px;\n font-weight: 700;\n}\n.cc-print-design-toolbar-group {\n gap: 7px;\n}\n.cc-print-design-toolbar-unit {\n margin-left: 8px;\n padding: 4px 9px;\n border: 1px solid var(--pd-border);\n border-radius: 5px;\n color: var(--pd-muted);\n background: var(--pd-surface);\n font-size: var(--pd-secondary-font-size);\n white-space: nowrap;\n}\n.cc-print-design-clock-options {\n grid-column: 1 / -1;\n display: flex;\n flex-wrap: wrap;\n gap: 8px 16px;\n}\n.cc-print-design-save-status {\n max-width: 120px;\n overflow: hidden;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-template-list {\n gap: 9px;\n}\n.cc-print-design-template-card {\n display: flex;\n flex-direction: column;\n min-height: 58px;\n padding: 8px;\n border: 1px solid var(--pd-border);\n border-radius: 7px;\n background: var(--pd-surface);\n}\n.cc-print-design-template-card.selected {\n border-color: var(--pd-selected-border);\n box-shadow: 0 0 0 2px var(--pd-selected);\n}\n.cc-print-design-template-select,\n.cc-print-design-template-heading {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 10px;\n}\n.cc-print-design-template-heading {\n flex-wrap: wrap;\n}\n.cc-print-design-template-heading > .cc-print-design-page-thumbnail {\n flex: 0 0 31px;\n}\n.cc-print-design-template-heading > .cc-print-design-template-label {\n flex: 1 1 calc(100% - 41px);\n}\n.cc-print-design-template-heading > .canvas-react-button {\n width: 26px;\n height: 26px;\n flex: 0 0 26px;\n}\n.cc-print-design-template-heading > .canvas-react-button:first-of-type {\n margin-left: auto;\n}\n.cc-print-design-template-select {\n width: 100%;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--pd-text);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-template-select.selected,\n.cc-print-design-template-versions button.selected {\n color: var(--pd-primary);\n font-weight: 600;\n}\n.cc-print-design-template-label {\n display: flex;\n min-width: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-template-label strong {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size);\n}\n.cc-print-design-template-label small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size);\n}\n.cc-print-design-template-invalid {\n color: var(--pd-danger);\n font-size: var(--pd-secondary-font-size);\n font-weight: 600;\n}\n.cc-print-design-template-versions {\n display: flex;\n flex-direction: column;\n margin: 7px 0 0 41px;\n border-top: 1px solid var(--pd-border);\n}\n.cc-print-design-template-version {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-template-version > button:first-child {\n flex: 1;\n min-width: 0;\n padding: 7px 0;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n cursor: pointer;\n text-align: left;\n font-size: var(--pd-secondary-font-size);\n}\n.cc-print-design-template-version > .canvas-react-button {\n width: 24px;\n height: 24px;\n flex: 0 0 24px;\n padding: 0;\n border: 0;\n color: var(--pd-muted);\n background: transparent;\n}\n.cc-print-design-template-version > .canvas-react-button:hover:not(:disabled) {\n color: var(--pd-danger);\n}\n.cc-print-design-toolbar .canvas-react-button {\n box-sizing: border-box;\n width: 32px;\n height: 32px;\n flex: 0 0 32px;\n padding: 4px;\n}\n.cc-print-design-toolbar-separator {\n width: 1px;\n height: 22px;\n margin: 0 5px;\n background: var(--pd-border);\n}\n.cc-print-design-zoom-value {\n min-width: 40px;\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n text-align: center;\n}\n.cc-print-design-zoom-value input {\n box-sizing: border-box;\n width: 42px;\n padding: 3px 2px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text);\n font: inherit;\n text-align: right;\n}\n.cc-print-design-zoom-value input:focus {\n border-color: var(--pd-primary);\n outline: none;\n}\n.cc-print-design-panel-width-group {\n display: grid;\n gap: 6px;\n margin-bottom: 12px;\n}\n.cc-print-design-panel-width-group strong {\n font-size: var(--pd-primary-font-size);\n}\n.cc-print-design-custom-component-row {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-custom-component-row > .cc-print-design-component-item {\n flex: 1;\n min-width: 0;\n}\n.cc-print-design-toolbar button[aria-label] {\n position: relative;\n}\n.cc-print-design-toolbar button[aria-label]::after {\n position: absolute;\n z-index: 10;\n top: calc(100% + 8px);\n left: 50%;\n width: max-content;\n max-width: 220px;\n padding: 5px 8px;\n border-radius: 5px;\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n content: attr(aria-label);\n font-size: 12px;\n font-weight: 400;\n line-height: 1.35;\n opacity: 0;\n pointer-events: none;\n transform: translateX(-50%) translateY(-3px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n white-space: normal;\n}\n.cc-print-design-toolbar button[aria-label]:is(:hover, :focus-visible)::after {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n}\n.cc-print-design-workspace {\n flex: 1 1 auto;\n min-height: 0;\n}\n.cc-print-design-canvas-host {\n position: relative;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-side-host {\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n.cc-print-design-side-host[inert],\n.cc-print-design-properties-host[inert] {\n opacity: 0.72;\n}\n.cc-print-design-preview-navigation {\n display: flex;\n align-items: center;\n gap: 6px;\n white-space: nowrap;\n}\n.cc-print-design-preview-navigation > span {\n min-width: 44px;\n text-align: center;\n font-variant-numeric: tabular-nums;\n}\n.cc-print-design-mobile-nav {\n display: none;\n}\n.cc-print-design-panels {\n width: 100%;\n height: 100%;\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item {\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(1),\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(3) {\n background: var(--pd-surface);\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(2) {\n overflow: hidden;\n background: var(--pd-workspace);\n}\n.cc-print-design-canvas-frame {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-left-panel,\n.cc-print-design-properties {\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n flex-direction: column;\n overflow: auto;\n scrollbar-width: none;\n background: var(--pd-surface);\n}\n.cc-print-design-left-panel::-webkit-scrollbar,\n.cc-print-design-properties::-webkit-scrollbar {\n display: none;\n}\n.cc-print-design-properties-host {\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n.cc-print-design-tabs {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n box-sizing: border-box;\n height: var(--pd-panel-header-height);\n flex: 0 0 var(--pd-panel-header-height);\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n}\n.cc-print-design-tabs button {\n position: relative;\n flex: 1;\n border: 0;\n color: var(--pd-muted);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-tabs button.active {\n color: var(--pd-primary);\n}\n.cc-print-design-tabs button.active::after {\n position: absolute;\n right: 18px;\n bottom: -1px;\n left: 18px;\n height: 2px;\n background: var(--pd-primary);\n content: "";\n}\n.cc-print-design-component-list,\n.cc-print-design-layer-list,\n.cc-print-design-page-list {\n padding: 14px 12px;\n}\n.cc-print-design-section-title {\n margin: 0;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n font-weight: 600;\n letter-spacing: 0.04em;\n}\n.cc-print-design-component-list .cc-print-design-section-title,\n.cc-print-design-layer-list .cc-print-design-section-title {\n margin: 3px 3px 10px;\n}\n.cc-print-design-component-item {\n display: flex;\n width: 100%;\n height: 38px;\n align-items: center;\n gap: 10px;\n padding: 0 9px;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--pd-text);\n background: var(--pd-surface);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-component-item:hover {\n border-color: var(--pd-selected-border);\n color: var(--pd-primary);\n background: var(--pd-selected);\n}\n.cc-print-design-component-item > span {\n display: grid;\n width: 22px;\n height: 22px;\n place-items: center;\n border-radius: 5px;\n color: var(--pd-icon);\n background: var(--pd-selected);\n font-size: 15px;\n}\n.cc-print-design-component-item b {\n margin-left: auto;\n color: var(--pd-muted);\n font-weight: 400;\n}\n.cc-print-design-hint {\n margin: 12px 4px;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n line-height: 1.6;\n}\n.cc-print-design-layer-item {\n display: flex;\n width: 100%;\n height: 34px;\n align-items: center;\n gap: 8px;\n padding: 0 7px;\n border: 0;\n border-radius: 5px;\n color: var(--pd-text);\n background: transparent;\n text-align: left;\n}\n.cc-print-design-layer-item:hover {\n background: var(--pd-hover);\n}\n.cc-print-design-layer-item.selected {\n color: var(--pd-primary);\n background: var(--pd-selected);\n}\n.cc-print-design-layer-select {\n display: flex;\n min-width: 0;\n height: 100%;\n flex: 1;\n align-items: center;\n gap: 8px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-layer-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-layer-delete,\n.cc-print-design-layer-lock {\n width: 23px;\n height: 23px;\n flex: 0 0 23px;\n border: 0;\n border-radius: 4px;\n color: var(--pd-muted);\n background: transparent;\n cursor: pointer;\n font-size: 17px;\n}\n.cc-print-design-layer-delete:hover {\n color: var(--pd-danger);\n background: var(--pd-surface);\n}\n.cc-print-design-layer-lock:hover,\n.cc-print-design-layer-lock[aria-pressed=true] {\n color: var(--pd-primary);\n background: var(--pd-surface);\n}\n.cc-print-design-empty {\n padding: 20px 0;\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n text-align: center;\n}\n.cc-print-design-page-list {\n display: flex;\n flex-direction: column;\n gap: 9px;\n}\n.cc-print-design-page-list-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin: 1px 3px 4px;\n}\n.cc-print-design-page-list-head .cc-print-design-add-link {\n border: 0;\n padding: 2px 0;\n color: var(--pd-primary);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-add-link:hover:not(:disabled) {\n text-decoration: underline;\n}\n.cc-print-design-add-link:disabled {\n color: var(--pd-muted);\n cursor: not-allowed;\n}\n.cc-print-design-page-card {\n display: flex;\n min-height: 58px;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border: 1px solid var(--pd-border);\n border-radius: 7px;\n background: var(--pd-surface);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-page-card.selected {\n border-color: var(--pd-selected-border);\n box-shadow: 0 0 0 2px var(--pd-selected);\n}\n.cc-print-design-page-thumbnail {\n display: grid;\n width: 31px;\n height: 40px;\n place-items: center;\n border: 1px solid var(--pd-border);\n border-radius: 3px;\n color: var(--pd-muted);\n background: var(--pd-subtle);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-card > span:last-child {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-page-card strong {\n overflow: hidden;\n color: var(--pd-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-page-card small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-shortcut {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin: auto 12px 12px;\n padding: 10px 9px;\n border-top: 1px solid var(--pd-border);\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-shortcut div {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-page-shortcut strong {\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-page-shortcut button {\n padding: 5px 7px;\n border: 1px solid var(--pd-border);\n border-radius: 4px;\n color: var(--pd-muted);\n background: var(--pd-surface);\n cursor: pointer;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-properties-title {\n display: flex;\n box-sizing: border-box;\n height: var(--pd-panel-header-height);\n flex: 0 0 var(--pd-panel-header-height);\n align-items: center;\n gap: 8px;\n padding: 0 15px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-properties .canvas-react-button {\n font-size: var(--canvas-react-font-size, 14px);\n}\n.cc-print-design-properties-title strong {\n flex-shrink: 0;\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-properties-title span {\n min-width: 0;\n overflow: hidden;\n color: var(--pd-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-property-section {\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-divider);\n}\n.cc-print-design-property-section > .canvas-react-collapse-panel-trigger {\n box-sizing: border-box;\n height: calc(var(--pd-panel-header-height) - 1px);\n padding: 0 14px;\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-editor .canvas-react-collapse-panel-title {\n color: var(--pd-text);\n}\n.cc-print-design-property-section > .canvas-react-collapse-panel-content {\n padding: 0 14px 15px;\n}\n.cc-print-design-property-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 11px 9px;\n}\n.cc-print-design-field {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 5px;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-field > :last-child {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-field-full {\n grid-column: 1 / -1;\n}\n.cc-print-design-text-size-rule {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 5px;\n}\n.cc-print-design-text-editor::-webkit-scrollbar {\n display: none;\n}\n.cc-print-design-template-property-fields {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.cc-print-design-template-property-fields time {\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-field .canvas-react-input,\n.cc-print-design-field .canvas-react-input-affix-wrapper,\n.cc-print-design-field .canvas-react-select,\n.cc-print-design-field .canvas-react-color {\n width: 100%;\n}\n.cc-print-design-paper-row {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-paper-row > .canvas-react-select {\n flex: 1;\n width: 0;\n min-width: 0;\n}\n.cc-print-design-paper-actions {\n display: flex;\n flex: none;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-paper-actions .canvas-react-button {\n width: 32px;\n padding: 6px;\n}\n.cc-print-design-paper-dialog {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n}\n.cc-print-design-paper-list {\n max-height: min(32vh, 240px);\n overflow: auto;\n border: 1px solid var(--canvas-react-color-border, #d9d9d9);\n border-radius: 4px;\n}\n.cc-print-design-paper-item {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 36px 36px;\n align-items: center;\n gap: 3px;\n min-height: 48px;\n padding: 4px 8px 4px 12px;\n}\n.cc-print-design-paper-item .canvas-react-button {\n width: 36px;\n padding: 8px;\n}\n.cc-print-design-paper-item + .cc-print-design-paper-item {\n border-top: 1px solid var(--canvas-react-color-border, #d9d9d9);\n}\n.cc-print-design-paper-item > div {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 8px;\n min-width: 0;\n}\n.cc-print-design-paper-item strong {\n overflow-wrap: anywhere;\n}\n.cc-print-design-paper-item span,\n.cc-print-design-paper-empty {\n color: var(--pd-muted, #667085);\n}\n.cc-print-design-paper-empty {\n margin: 4px 0;\n}\n.cc-print-design-paper-form,\n.cc-print-design-paper-form label {\n display: flex;\n flex-direction: column;\n gap: 7px;\n min-width: 0;\n}\n.cc-print-design-paper-form label > span:first-child {\n font-size: 12px;\n}\n.cc-print-design-paper-dimensions {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n}\n.cc-print-design-paper-error {\n margin: 0;\n color: #c2410c;\n font-size: 12px;\n}\n.cc-print-design-paper-footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n@media (max-width: 440px) {\n .cc-print-design-paper-dimensions {\n grid-template-columns: 1fr;\n }\n}\n.cc-print-design-margin-grid {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n}\n@media (max-width: 900px) {\n .cc-print-design-toolbar {\n gap: 8px;\n padding: 0 9px;\n }\n .cc-print-design-brand {\n min-width: 120px;\n }\n .cc-print-design-brand small,\n .cc-print-design-toolbar-group:nth-child(2) .cc-print-design-toolbar-separator {\n display: none;\n }\n .cc-print-design-toolbar-group {\n gap: 4px;\n }\n}\n@media (max-width: 700px) {\n .cc-print-design-toolbar {\n flex-basis: 50px;\n justify-content: flex-start;\n overflow-x: auto;\n white-space: nowrap;\n }\n .cc-print-design-brand {\n flex: 0 0 auto;\n }\n .cc-print-design-toolbar-group {\n flex: 0 0 auto;\n }\n .cc-print-design-mobile-nav {\n display: flex;\n height: 36px;\n flex: 0 0 36px;\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n }\n .cc-print-design-mobile-nav button {\n flex: 1;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n font: inherit;\n }\n .cc-print-design-mobile-nav button.active {\n border-bottom: 2px solid var(--pd-primary);\n color: var(--pd-primary);\n font-weight: 600;\n }\n .cc-print-design-panels .canvas-react-resizable-panels-divider {\n display: none;\n }\n .cc-print-design-panels > .canvas-react-resizable-panels-item {\n display: none;\n width: 100% !important;\n flex: 1 1 100% !important;\n }\n .cc-print-design-panels .canvas-react-resizable-panel {\n width: 100% !important;\n max-width: none !important;\n height: 100% !important;\n flex: 1 1 100% !important;\n }\n .cc-print-design-editor[data-mobile-view=panel] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(1),\n .cc-print-design-editor[data-mobile-view=canvas] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(2),\n .cc-print-design-editor[data-mobile-view=properties] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(3) {\n display: flex;\n }\n}\n.cc-print-design-settings {\n --canvas-react-control-height: 28px;\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n padding: 0;\n}\n.cc-print-design-settings-toggle {\n display: flex;\n min-height: 28px;\n align-items: center;\n margin: 6px 0;\n}\n.cc-print-design-settings-global-actions {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px 12px;\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-settings-global-actions .canvas-react-button {\n flex-shrink: 0;\n margin-left: auto;\n padding-inline: 4px;\n border-color: transparent;\n background: transparent;\n color: var(--pd-primary, #1677ff);\n}\n.cc-print-design-settings-global-actions .canvas-react-checkbox {\n min-width: 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-theme-options {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding-top: 12px;\n}\n.cc-print-design-theme-option {\n display: flex;\n min-width: 0;\n min-height: 60px;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 5px;\n padding: 6px 8px;\n border: 1px solid var(--pd-border);\n border-radius: 4px;\n background: var(--pd-surface);\n color: var(--pd-text);\n cursor: pointer;\n font: inherit;\n white-space: nowrap;\n}\n.cc-print-design-theme-option:hover,\n.cc-print-design-theme-option[aria-pressed=true] {\n border-color: var(--pd-primary);\n}\n.cc-print-design-theme-option[aria-pressed=true] {\n background: var(--pd-selected);\n}\n.cc-print-design-theme-option:focus-visible {\n outline: 2px solid var(--pd-primary);\n outline-offset: 2px;\n}\n.cc-print-design-theme-swatches {\n display: flex;\n width: 37px;\n height: 19px;\n flex: 0 0 37px;\n overflow: hidden;\n border: 1px solid var(--pd-border);\n border-radius: 3px;\n}\n.cc-print-design-theme-swatches > span {\n flex: 1;\n}\n.cc-print-design-settings-toggle .canvas-react-checkbox {\n min-width: 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-settings-field {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 6px;\n margin-top: 14px;\n}\n.cc-print-design-settings-field > span:first-child {\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n line-height: 18px;\n}\n.cc-print-design-settings-field .canvas-react-color-wrap {\n height: 28px;\n}\n.cc-print-design-settings .canvas-react-color-preview {\n width: 20px;\n height: 20px;\n}\n.cc-print-design-settings .canvas-react-input-number-handler {\n flex-basis: 24px;\n}\n.cc-print-design-settings .cc-print-design-hint {\n margin: 14px 0 0;\n}\n.cc-print-design-chart-data {\n padding: 12px;\n min-width: 0;\n --canvas-react-control-height: 28px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-chart-data h4 {\n margin: 12px 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-chart-data > label,\n.cc-print-design-chart-series > label {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 10px 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-chart-row {\n display: flex;\n gap: 6px;\n margin: 6px 0;\n min-width: 0;\n}\n.cc-print-design-chart-row > :first-child {\n flex: 1;\n min-width: 0;\n}\n.cc-print-design-chart-row button {\n flex-shrink: 0;\n padding-inline: 8px;\n}\n.cc-print-design-chart-series {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 8px;\n margin: 8px 0;\n}\n.cc-print-design-chart-data pre {\n max-height: 200px;\n overflow: auto;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-chart-simple {\n margin: 10px 0;\n}\n.cc-print-design-table-data {\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n --canvas-react-control-height: 28px;\n}\n.cc-print-design-table-data h4 {\n font-size: var(--pd-primary-font-size, 13px);\n margin: 12px 0;\n}\n.cc-print-design-table-data label:not(.canvas-react-checkbox) {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 10px 0;\n}\n.cc-print-design-compact-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n.cc-print-design-compact-grid > .canvas-react-checkbox {\n grid-column: 1 / -1;\n}\n.cc-print-design-table-data.cc-print-design-compact-grid label:not(.canvas-react-checkbox) {\n min-width: 0;\n gap: 4px;\n margin: 0;\n}\n.cc-print-design-compact-grid .canvas-react-input-number,\n.cc-print-design-compact-grid .canvas-react-color-picker {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-table-column {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n margin-bottom: 8px;\n overflow: hidden;\n}\n.cc-print-design-column-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n.cc-print-design-column-heading > span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-column-heading small {\n flex-shrink: 0;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n font-weight: normal;\n}\n.cc-print-design-column-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px;\n}\n.cc-print-design-column-grid > * {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-column-grid > .cc-print-design-column-half {\n grid-column: span 1;\n}\n.cc-print-design-table-data .cc-print-design-column-grid label:not(.canvas-react-checkbox),\n.cc-print-design-column-grid > .cc-print-design-field {\n gap: 4px;\n margin: 0;\n}\n.cc-print-design-column-grid .canvas-react-input-number {\n min-width: 0;\n width: 100%;\n}\n.cc-print-design-column-actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n}\n.cc-print-design-column-actions > .canvas-react-button {\n padding: 4px;\n}\n.cc-print-design-table-json {\n margin: 12px 0;\n}\n.cc-print-design-table-json textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 160px;\n resize: vertical;\n font-size: var(--pd-primary-font-size, 13px);\n margin: 8px 0;\n}\n.cc-print-design-table-row {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 8px;\n margin: 8px 0;\n}\n.cc-print-design-table-data pre {\n max-height: 200px;\n overflow: auto;\n font-size: var(--pd-primary-font-size, 13px);\n overscroll-behavior: contain;\n}\n.cc-print-design-table-colors > div {\n border-bottom: 1px solid var(--pd-border);\n padding-bottom: 8px;\n}\n.cc-print-design-layer-controls {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 8px 0;\n}\n.cc-print-design-layer-controls .canvas-react-button {\n padding: 6px;\n}\n.cc-print-design-layer-item {\n position: relative;\n}\n.cc-print-design-layer-drag {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n padding: 4px;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n cursor: grab;\n}\n.cc-print-design-layer-drag:active {\n cursor: grabbing;\n}\n.cc-print-design-layer-drag:disabled {\n cursor: default;\n opacity: 0.4;\n}\n.cc-print-design-layer-children {\n margin-left: 12px;\n border-left: 1px solid var(--pd-divider);\n padding-left: 3px;\n}\n.cc-print-design-layer-drag {\n touch-action: none;\n}\n.cc-print-design-layer-menu {\n padding: 4px;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-layer-menu button {\n display: flex;\n gap: 8px;\n align-items: center;\n width: 100%;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text);\n padding: 8px;\n cursor: pointer;\n}\n.cc-print-design-layer-menu button:hover:not(:disabled),\n.cc-print-design-layer-menu button:focus-visible {\n background: var(--pd-selected);\n}\n.cc-print-design-layer-menu button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.cc-print-design-layer-menu button > span:last-child {\n margin-left: auto;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-layer-list {\n user-select: none;\n}\n.cc-print-design-menu-separator {\n height: 1px;\n background: var(--pd-divider);\n margin: 4px 0;\n}\n.cc-print-design-layer-menu button.danger {\n color: var(--pd-danger);\n}\n.cc-print-design-layer-menu button > .cc-print-design-menu-label:last-child {\n margin-left: 0;\n color: inherit;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-layer-order-row {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.cc-print-design-layer-order-row > :first-child {\n flex: 1;\n min-width: 0;\n width: 0;\n}\n.cc-print-design-layer-order-row .cc-print-design-layer-controls {\n flex: none;\n flex-wrap: nowrap;\n gap: 2px;\n margin: 0;\n}\n.cc-print-design-alignment-controls {\n display: flex;\n gap: 6px;\n}\n.cc-print-design-alignment-controls .canvas-react-button {\n flex: 1;\n padding: 6px;\n}\n.cc-print-design-alignment-controls .canvas-react-button[aria-pressed=true] {\n color: var(--pd-primary, #2563eb);\n border-color: var(--pd-primary, #2563eb);\n background: var(--pd-selected);\n}\n.cc-print-design-data-fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n min-width: 0;\n}\n.cc-print-design-data-preview {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n margin: 0;\n}\n.cc-print-design-layer-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.cc-print-design-layer-heading .cc-print-design-section-title {\n margin: 0;\n}\n.cc-print-design-link {\n border: 0;\n padding: 0;\n color: var(--pd-primary);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-link:disabled {\n color: #b8c0cc;\n cursor: not-allowed;\n}\n.cc-print-design-editor .canvas-react-button:hover:not(:disabled) {\n border-color: var(--pd-primary);\n color: var(--pd-primary);\n}\n.cc-print-design-editor .canvas-react-button-primary {\n border-color: var(--pd-primary);\n background: var(--pd-primary);\n color: #fff;\n}\n.cc-print-design-editor .canvas-react-button-primary:hover:not(:disabled) {\n border-color: var(--canvas-react-color-primary-hover);\n background: var(--canvas-react-color-primary-hover);\n color: #fff;\n}\n.cc-print-design-editor .canvas-react-radio input:checked + .canvas-react-radio-mark {\n border-color: var(--pd-primary);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-select-disabled,\n.cc-print-design-editor[data-theme=dark] .canvas-react-number-input-affix-wrapper-disabled,\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled {\n background: var(--pd-subtle);\n color: var(--pd-muted);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled:hover {\n border-color: var(--pd-border);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled .canvas-react-input-number-input,\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled .canvas-react-input-number-handler:disabled {\n color: var(--pd-muted);\n}\n.cc-print-design-editor .cc-print-design-field > span:first-child,\n.cc-print-design-editor .cc-print-design-settings-field > span:first-child,\n.cc-print-design-editor .cc-print-design-table-data label,\n.cc-print-design-editor .cc-print-design-chart-data label {\n font-size: var(--pd-label-font-size, 12px);\n color: var(--pd-muted);\n}\n.cc-print-design-editor .canvas-react-input,\n.cc-print-design-editor .canvas-react-textarea,\n.cc-print-design-editor .canvas-react-input-number-input {\n font-size: var(--pd-primary-font-size, 13px);\n color: var(--pd-text);\n}\n.cc-print-design-row-settings:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n.cc-print-design-row-settings > * {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-row-settings > .cc-print-design-column-half {\n grid-column: span 1;\n margin: 0;\n gap: 4px;\n}\n.cc-print-design-row-settings .canvas-react-input-number {\n min-width: 0;\n width: 100%;\n}\n.cc-print-design-row-settings .cc-print-design-hint {\n margin: 0;\n}\n.cc-print-design-data-compact {\n padding: 8px;\n}\n.cc-print-design-data-compact .cc-print-design-hint {\n margin: 6px 0;\n}\n.cc-print-design-data-compact .cc-print-design-table-json {\n margin: 6px 0;\n}\n.cc-print-design-data-compact .cc-print-design-table-row {\n padding: 0;\n margin: 6px 0;\n overflow: hidden;\n}\n.cc-print-design-static-row-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px;\n}\n.cc-print-design-static-row-grid > * {\n min-width: 0;\n}\n.cc-print-design-static-tasks > strong,\n.cc-print-design-task-dependencies > strong {\n display: block;\n margin: 8px 0 4px;\n}\n.cc-print-design-gantt-connection-title {\n display: block;\n margin: 12px 0 6px;\n}\n.cc-print-design-task-title {\n padding: 8px;\n font-weight: 600;\n}\n.cc-print-design-task-dependencies {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-task-dependency-row {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid #e7edf5;\n}\n.cc-print-design-task-dependency-row > * {\n min-width: 0;\n}\n.cc-print-design-table-data .cc-print-design-static-row-grid label:not(.canvas-react-checkbox) {\n margin: 0;\n gap: 4px;\n overflow-wrap: anywhere;\n}\n.cc-print-design-static-row-grid .canvas-react-input-number {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-static-row-grid > .cc-print-design-table-json,\n.cc-print-design-static-row-actions {\n grid-column: 1 / -1;\n}\n.cc-print-design-static-row-actions {\n display: flex;\n justify-content: flex-end;\n}\n.cc-print-design-static-row-actions > .canvas-react-button {\n padding: 4px;\n}\n');
9634
+ styleInject('.cc-print-design-editor {\n position: relative;\n --pd-border: #e4e8ef;\n --pd-text: var(--canvas-react-color-text, #263244);\n --pd-muted: var(--canvas-react-color-text-muted, #8993a2);\n --pd-primary: #1677ff;\n --pd-background: #f7f8fa;\n --pd-surface: #fff;\n --pd-workspace: #e9edf3;\n --pd-hover: #f5f7fa;\n --pd-selected: #edf4ff;\n --pd-subtle: #fafbfd;\n --pd-icon: #4279cb;\n --pd-divider: #edf0f4;\n --pd-selected-border: #86b4ff;\n --pd-danger: #dc2626;\n --pd-brand-start: #428cff;\n --pd-brand-end: #1261d8;\n --canvas-react-shadow-focus: 0 0 0 2px color-mix(in srgb, var(--pd-primary) 18%, transparent);\n --pd-label-font-size: var(--canvas-react-font-size-label, 12px);\n --pd-primary-font-size: var(--canvas-react-font-size, 13px);\n --pd-secondary-font-size: var(--canvas-react-font-size-secondary, 11px);\n --pd-panel-header-height: 36px;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n overflow: hidden;\n color: var(--pd-text);\n background: var(--pd-background);\n font-family:\n Inter,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n "PingFang SC",\n "Microsoft YaHei",\n sans-serif;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-editor:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n}\n.cc-print-design-toolbar {\n z-index: 2;\n display: flex;\n flex: 0 0 58px;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n padding: 0 18px;\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n}\n.cc-print-design-brand,\n.cc-print-design-brand > div,\n.cc-print-design-toolbar-group {\n display: flex;\n align-items: center;\n}\n.cc-print-design-brand {\n gap: 10px;\n min-width: 180px;\n}\n.cc-print-design-brand > div {\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n}\n.cc-print-design-brand strong {\n max-width: 170px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-brand small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-brand-mark {\n display: grid;\n width: 32px;\n height: 32px;\n place-items: center;\n border-radius: 9px;\n color: #fff;\n background:\n linear-gradient(\n 145deg,\n var(--pd-brand-start),\n var(--pd-brand-end));\n font-size: 16px;\n font-weight: 700;\n}\n.cc-print-design-toolbar-group {\n gap: 7px;\n}\n.cc-print-design-toolbar-unit {\n margin-left: 8px;\n padding: 4px 9px;\n border: 1px solid var(--pd-border);\n border-radius: 5px;\n color: var(--pd-muted);\n background: var(--pd-surface);\n font-size: var(--pd-secondary-font-size);\n white-space: nowrap;\n}\n.cc-print-design-clock-options {\n grid-column: 1 / -1;\n display: flex;\n flex-wrap: wrap;\n gap: 8px 16px;\n}\n.cc-print-design-save-status {\n max-width: 120px;\n overflow: hidden;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-template-list {\n gap: 9px;\n}\n.cc-print-design-template-card {\n display: flex;\n flex-direction: column;\n min-height: 58px;\n padding: 8px;\n border: 1px solid var(--pd-border);\n border-radius: 7px;\n background: var(--pd-surface);\n}\n.cc-print-design-template-card.selected {\n border-color: var(--pd-selected-border);\n box-shadow: 0 0 0 2px var(--pd-selected);\n}\n.cc-print-design-template-select,\n.cc-print-design-template-heading {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 10px;\n}\n.cc-print-design-template-heading {\n flex-wrap: wrap;\n}\n.cc-print-design-template-heading > .cc-print-design-page-thumbnail {\n flex: 0 0 31px;\n}\n.cc-print-design-template-heading > .cc-print-design-template-label {\n flex: 1 1 calc(100% - 41px);\n}\n.cc-print-design-template-heading > .canvas-react-button {\n width: 26px;\n height: 26px;\n flex: 0 0 26px;\n}\n.cc-print-design-template-heading > .canvas-react-button:first-of-type {\n margin-left: auto;\n}\n.cc-print-design-template-select {\n width: 100%;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--pd-text);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-template-select.selected,\n.cc-print-design-template-versions button.selected {\n color: var(--pd-primary);\n font-weight: 600;\n}\n.cc-print-design-template-label {\n display: flex;\n min-width: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-template-label strong {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size);\n}\n.cc-print-design-template-label small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size);\n}\n.cc-print-design-template-invalid {\n color: var(--pd-danger);\n font-size: var(--pd-secondary-font-size);\n font-weight: 600;\n}\n.cc-print-design-template-versions {\n display: flex;\n flex-direction: column;\n margin: 7px 0 0 41px;\n border-top: 1px solid var(--pd-border);\n}\n.cc-print-design-template-version {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-template-version > button:first-child {\n flex: 1;\n min-width: 0;\n padding: 7px 0;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n cursor: pointer;\n text-align: left;\n font-size: var(--pd-secondary-font-size);\n}\n.cc-print-design-template-version > .canvas-react-button {\n width: 24px;\n height: 24px;\n flex: 0 0 24px;\n padding: 0;\n border: 0;\n color: var(--pd-muted);\n background: transparent;\n}\n.cc-print-design-template-version > .canvas-react-button:hover:not(:disabled) {\n color: var(--pd-danger);\n}\n.cc-print-design-toolbar .canvas-react-button {\n box-sizing: border-box;\n width: 32px;\n height: 32px;\n flex: 0 0 32px;\n padding: 4px;\n}\n.cc-print-design-toolbar-separator {\n width: 1px;\n height: 22px;\n margin: 0 5px;\n background: var(--pd-border);\n}\n.cc-print-design-zoom-value {\n min-width: 40px;\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n text-align: center;\n}\n.cc-print-design-zoom-value input {\n box-sizing: border-box;\n width: 42px;\n padding: 3px 2px;\n border: 1px solid transparent;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text);\n font: inherit;\n text-align: right;\n}\n.cc-print-design-zoom-value input:focus {\n border-color: var(--pd-primary);\n outline: none;\n}\n.cc-print-design-panel-width-group {\n display: grid;\n gap: 6px;\n margin-bottom: 12px;\n}\n.cc-print-design-panel-width-group strong {\n font-size: var(--pd-primary-font-size);\n}\n.cc-print-design-custom-component-row {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-custom-component-row > .cc-print-design-component-item {\n flex: 1;\n min-width: 0;\n}\n.cc-print-design-toolbar button[aria-label] {\n position: relative;\n}\n.cc-print-design-toolbar button[aria-label]::after {\n position: absolute;\n z-index: 10;\n top: calc(100% + 8px);\n left: 50%;\n width: max-content;\n max-width: 220px;\n padding: 5px 8px;\n border-radius: 5px;\n background: rgba(0, 0, 0, 0.85);\n color: #fff;\n content: attr(aria-label);\n font-size: 12px;\n font-weight: 400;\n line-height: 1.35;\n opacity: 0;\n pointer-events: none;\n transform: translateX(-50%) translateY(-3px);\n transition: opacity 0.15s ease, transform 0.15s ease;\n white-space: normal;\n}\n.cc-print-design-toolbar button[aria-label]:is(:hover, :focus-visible)::after {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n}\n.cc-print-design-workspace {\n flex: 1 1 auto;\n min-height: 0;\n}\n.cc-print-design-canvas-host {\n position: relative;\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-side-host {\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n.cc-print-design-side-host[inert],\n.cc-print-design-properties-host[inert] {\n opacity: 0.72;\n}\n.cc-print-design-preview-navigation {\n display: flex;\n align-items: center;\n gap: 6px;\n white-space: nowrap;\n}\n.cc-print-design-preview-navigation > span {\n min-width: 44px;\n text-align: center;\n font-variant-numeric: tabular-nums;\n}\n.cc-print-design-mobile-nav {\n display: none;\n}\n.cc-print-design-panels {\n width: 100%;\n height: 100%;\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item {\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(1),\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(3) {\n background: var(--pd-surface);\n}\n.cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(2) {\n overflow: hidden;\n background: var(--pd-workspace);\n}\n.cc-print-design-canvas-frame {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n.cc-print-design-left-panel,\n.cc-print-design-properties {\n display: flex;\n width: 100%;\n height: 100%;\n min-width: 0;\n flex-direction: column;\n overflow: auto;\n scrollbar-width: none;\n background: var(--pd-surface);\n}\n.cc-print-design-left-panel::-webkit-scrollbar,\n.cc-print-design-properties::-webkit-scrollbar {\n display: none;\n}\n.cc-print-design-properties-host {\n width: 100%;\n height: 100%;\n min-height: 0;\n}\n.cc-print-design-tabs {\n position: sticky;\n top: 0;\n z-index: 1;\n display: flex;\n box-sizing: border-box;\n height: var(--pd-panel-header-height);\n flex: 0 0 var(--pd-panel-header-height);\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n}\n.cc-print-design-tabs button {\n position: relative;\n flex: 1;\n border: 0;\n color: var(--pd-muted);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-tabs button.active {\n color: var(--pd-primary);\n}\n.cc-print-design-tabs button.active::after {\n position: absolute;\n right: 18px;\n bottom: -1px;\n left: 18px;\n height: 2px;\n background: var(--pd-primary);\n content: "";\n}\n.cc-print-design-component-list,\n.cc-print-design-layer-list,\n.cc-print-design-page-list {\n padding: 14px 12px;\n}\n.cc-print-design-section-title {\n margin: 0;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n font-weight: 600;\n letter-spacing: 0.04em;\n}\n.cc-print-design-component-list .cc-print-design-section-title,\n.cc-print-design-layer-list .cc-print-design-section-title {\n margin: 3px 3px 10px;\n}\n.cc-print-design-component-item {\n display: flex;\n width: 100%;\n height: 38px;\n align-items: center;\n gap: 10px;\n padding: 0 9px;\n border: 1px solid transparent;\n border-radius: 6px;\n color: var(--pd-text);\n background: var(--pd-surface);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-component-item:hover {\n border-color: var(--pd-selected-border);\n color: var(--pd-primary);\n background: var(--pd-selected);\n}\n.cc-print-design-component-item > span {\n display: grid;\n width: 22px;\n height: 22px;\n place-items: center;\n border-radius: 5px;\n color: var(--pd-icon);\n background: var(--pd-selected);\n font-size: 15px;\n}\n.cc-print-design-component-item b {\n margin-left: auto;\n color: var(--pd-muted);\n font-weight: 400;\n}\n.cc-print-design-hint {\n margin: 12px 4px;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n line-height: 1.6;\n}\n.cc-print-design-layer-item {\n display: flex;\n width: 100%;\n height: 34px;\n align-items: center;\n gap: 8px;\n padding: 0 7px;\n border: 0;\n border-radius: 5px;\n color: var(--pd-text);\n background: transparent;\n text-align: left;\n}\n.cc-print-design-layer-item:hover {\n background: var(--pd-hover);\n}\n.cc-print-design-layer-item.selected {\n color: var(--pd-primary);\n background: var(--pd-selected);\n}\n.cc-print-design-layer-select {\n display: flex;\n min-width: 0;\n height: 100%;\n flex: 1;\n align-items: center;\n gap: 8px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-layer-name {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-layer-delete,\n.cc-print-design-layer-lock {\n width: 23px;\n height: 23px;\n flex: 0 0 23px;\n border: 0;\n border-radius: 4px;\n color: var(--pd-muted);\n background: transparent;\n cursor: pointer;\n font-size: 17px;\n}\n.cc-print-design-layer-delete:hover {\n color: var(--pd-danger);\n background: var(--pd-surface);\n}\n.cc-print-design-layer-lock:hover,\n.cc-print-design-layer-lock[aria-pressed=true] {\n color: var(--pd-primary);\n background: var(--pd-surface);\n}\n.cc-print-design-empty {\n padding: 20px 0;\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n text-align: center;\n}\n.cc-print-design-page-list {\n display: flex;\n flex-direction: column;\n gap: 9px;\n}\n.cc-print-design-page-list-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin: 1px 3px 4px;\n}\n.cc-print-design-page-list-head .cc-print-design-add-link {\n border: 0;\n padding: 2px 0;\n color: var(--pd-primary);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-add-link:hover:not(:disabled) {\n text-decoration: underline;\n}\n.cc-print-design-add-link:disabled {\n color: var(--pd-muted);\n cursor: not-allowed;\n}\n.cc-print-design-page-card {\n display: flex;\n min-height: 58px;\n align-items: center;\n gap: 10px;\n padding: 8px;\n border: 1px solid var(--pd-border);\n border-radius: 7px;\n background: var(--pd-surface);\n cursor: pointer;\n text-align: left;\n}\n.cc-print-design-page-card.selected {\n border-color: var(--pd-selected-border);\n box-shadow: 0 0 0 2px var(--pd-selected);\n}\n.cc-print-design-page-thumbnail {\n display: grid;\n width: 31px;\n height: 40px;\n place-items: center;\n border: 1px solid var(--pd-border);\n border-radius: 3px;\n color: var(--pd-muted);\n background: var(--pd-subtle);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-card > span:last-child {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-page-card strong {\n overflow: hidden;\n color: var(--pd-text);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-page-card small {\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-shortcut {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin: auto 12px 12px;\n padding: 10px 9px;\n border-top: 1px solid var(--pd-border);\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-page-shortcut div {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.cc-print-design-page-shortcut strong {\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-page-shortcut button {\n padding: 5px 7px;\n border: 1px solid var(--pd-border);\n border-radius: 4px;\n color: var(--pd-muted);\n background: var(--pd-surface);\n cursor: pointer;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-properties-title {\n display: flex;\n box-sizing: border-box;\n height: var(--pd-panel-header-height);\n flex: 0 0 var(--pd-panel-header-height);\n align-items: center;\n gap: 8px;\n padding: 0 15px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-properties .canvas-react-button {\n font-size: var(--canvas-react-font-size, 14px);\n}\n.cc-print-design-properties-title strong {\n flex-shrink: 0;\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-properties-title span {\n min-width: 0;\n overflow: hidden;\n color: var(--pd-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-property-section {\n flex-shrink: 0;\n border-bottom: 1px solid var(--pd-divider);\n}\n.cc-print-design-property-section > .canvas-react-collapse-panel-trigger {\n box-sizing: border-box;\n height: calc(var(--pd-panel-header-height) - 1px);\n padding: 0 14px;\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-editor .canvas-react-collapse-panel-title {\n color: var(--pd-text);\n}\n.cc-print-design-property-section > .canvas-react-collapse-panel-content {\n padding: 0 14px 15px;\n}\n.cc-print-design-property-grid {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 11px 9px;\n}\n.cc-print-design-field {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 5px;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-field > :last-child {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-field-full {\n grid-column: 1 / -1;\n}\n.cc-print-design-text-size-rule {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto auto;\n align-items: center;\n gap: 5px;\n}\n.cc-print-design-text-editor::-webkit-scrollbar {\n display: none;\n}\n.cc-print-design-template-property-fields {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n.cc-print-design-template-property-fields time {\n color: var(--pd-text);\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-field .canvas-react-input,\n.cc-print-design-field .canvas-react-input-affix-wrapper,\n.cc-print-design-field .canvas-react-select,\n.cc-print-design-field .canvas-react-color {\n width: 100%;\n}\n.cc-print-design-paper-row {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-paper-row > .canvas-react-select {\n flex: 1;\n width: 0;\n min-width: 0;\n}\n.cc-print-design-paper-actions {\n display: flex;\n flex: none;\n align-items: center;\n gap: 4px;\n}\n.cc-print-design-paper-actions .canvas-react-button {\n width: 32px;\n padding: 6px;\n}\n.cc-print-design-paper-dialog {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n}\n.cc-print-design-paper-list {\n max-height: min(32vh, 240px);\n overflow: auto;\n border: 1px solid var(--canvas-react-color-border, #d9d9d9);\n border-radius: 4px;\n}\n.cc-print-design-paper-item {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 36px 36px;\n align-items: center;\n gap: 3px;\n min-height: 48px;\n padding: 4px 8px 4px 12px;\n}\n.cc-print-design-paper-item .canvas-react-button {\n width: 36px;\n padding: 8px;\n}\n.cc-print-design-paper-item + .cc-print-design-paper-item {\n border-top: 1px solid var(--canvas-react-color-border, #d9d9d9);\n}\n.cc-print-design-paper-item > div {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 8px;\n min-width: 0;\n}\n.cc-print-design-paper-item strong {\n overflow-wrap: anywhere;\n}\n.cc-print-design-paper-item span,\n.cc-print-design-paper-empty {\n color: var(--pd-muted, #667085);\n}\n.cc-print-design-paper-empty {\n margin: 4px 0;\n}\n.cc-print-design-paper-form,\n.cc-print-design-paper-form label {\n display: flex;\n flex-direction: column;\n gap: 7px;\n min-width: 0;\n}\n.cc-print-design-paper-form label > span:first-child {\n font-size: 12px;\n}\n.cc-print-design-paper-dimensions {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 12px;\n}\n.cc-print-design-paper-error {\n margin: 0;\n color: #c2410c;\n font-size: 12px;\n}\n.cc-print-design-paper-footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n@media (max-width: 440px) {\n .cc-print-design-paper-dimensions {\n grid-template-columns: 1fr;\n }\n}\n.cc-print-design-margin-grid {\n display: grid;\n grid-column: 1 / -1;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n}\n@media (max-width: 900px) {\n .cc-print-design-toolbar {\n gap: 8px;\n padding: 0 9px;\n }\n .cc-print-design-brand {\n min-width: 120px;\n }\n .cc-print-design-brand small,\n .cc-print-design-toolbar-group:nth-child(2) .cc-print-design-toolbar-separator {\n display: none;\n }\n .cc-print-design-toolbar-group {\n gap: 4px;\n }\n}\n@media (max-width: 700px) {\n .cc-print-design-toolbar {\n flex-basis: 50px;\n justify-content: flex-start;\n overflow-x: auto;\n white-space: nowrap;\n }\n .cc-print-design-brand {\n flex: 0 0 auto;\n }\n .cc-print-design-toolbar-group {\n flex: 0 0 auto;\n }\n .cc-print-design-mobile-nav {\n display: flex;\n height: 36px;\n flex: 0 0 36px;\n border-bottom: 1px solid var(--pd-border);\n background: var(--pd-surface);\n }\n .cc-print-design-mobile-nav button {\n flex: 1;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n font: inherit;\n }\n .cc-print-design-mobile-nav button.active {\n border-bottom: 2px solid var(--pd-primary);\n color: var(--pd-primary);\n font-weight: 600;\n }\n .cc-print-design-panels .canvas-react-resizable-panels-divider {\n display: none;\n }\n .cc-print-design-panels > .canvas-react-resizable-panels-item {\n display: none;\n width: 100% !important;\n flex: 1 1 100% !important;\n }\n .cc-print-design-panels .canvas-react-resizable-panel {\n width: 100% !important;\n max-width: none !important;\n height: 100% !important;\n flex: 1 1 100% !important;\n }\n .cc-print-design-editor[data-mobile-view=panel] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(1),\n .cc-print-design-editor[data-mobile-view=canvas] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(2),\n .cc-print-design-editor[data-mobile-view=properties] .cc-print-design-panels > .canvas-react-resizable-panels-item:nth-child(3) {\n display: flex;\n }\n}\n.cc-print-design-settings {\n --canvas-react-control-height: 28px;\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n padding: 0;\n}\n.cc-print-design-settings-toggle {\n display: flex;\n min-height: 28px;\n align-items: center;\n margin: 6px 0;\n}\n.cc-print-design-settings-global-actions {\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-wrap: wrap;\n gap: 8px 12px;\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-settings-global-actions .canvas-react-button {\n flex-shrink: 0;\n margin-left: auto;\n padding-inline: 4px;\n border-color: transparent;\n background: transparent;\n color: var(--pd-primary, #1677ff);\n}\n.cc-print-design-settings-global-actions .canvas-react-checkbox {\n min-width: 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-theme-options {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding-top: 12px;\n}\n.cc-print-design-theme-option {\n display: flex;\n min-width: 0;\n min-height: 60px;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 5px;\n padding: 6px 8px;\n border: 1px solid var(--pd-border);\n border-radius: 4px;\n background: var(--pd-surface);\n color: var(--pd-text);\n cursor: pointer;\n font: inherit;\n white-space: nowrap;\n}\n.cc-print-design-theme-option:hover,\n.cc-print-design-theme-option[aria-pressed=true] {\n border-color: var(--pd-primary);\n}\n.cc-print-design-theme-option[aria-pressed=true] {\n background: var(--pd-selected);\n}\n.cc-print-design-theme-option:focus-visible {\n outline: 2px solid var(--pd-primary);\n outline-offset: 2px;\n}\n.cc-print-design-theme-swatches {\n display: flex;\n width: 37px;\n height: 19px;\n flex: 0 0 37px;\n overflow: hidden;\n border: 1px solid var(--pd-border);\n border-radius: 3px;\n}\n.cc-print-design-theme-swatches > span {\n flex: 1;\n}\n.cc-print-design-settings-toggle .canvas-react-checkbox {\n min-width: 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-settings-field {\n display: flex;\n min-width: 0;\n flex-direction: column;\n gap: 6px;\n margin-top: 14px;\n}\n.cc-print-design-settings-field > span:first-child {\n color: var(--pd-muted);\n font-size: var(--pd-primary-font-size, 13px);\n line-height: 18px;\n}\n.cc-print-design-settings-field .canvas-react-color-wrap {\n height: 28px;\n}\n.cc-print-design-settings .canvas-react-color-preview {\n width: 20px;\n height: 20px;\n}\n.cc-print-design-settings .canvas-react-input-number-handler {\n flex-basis: 24px;\n}\n.cc-print-design-settings .cc-print-design-hint {\n margin: 14px 0 0;\n}\n.cc-print-design-chart-data {\n padding: 12px;\n min-width: 0;\n --canvas-react-control-height: 28px;\n border-bottom: 1px solid var(--pd-border);\n}\n.cc-print-design-chart-data h4 {\n margin: 12px 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-chart-data > label,\n.cc-print-design-chart-series > label {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 10px 0;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-chart-row {\n display: flex;\n gap: 6px;\n margin: 6px 0;\n min-width: 0;\n}\n.cc-print-design-chart-row > :first-child {\n flex: 1;\n min-width: 0;\n}\n.cc-print-design-chart-row button {\n flex-shrink: 0;\n padding-inline: 8px;\n}\n.cc-print-design-chart-series {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 8px;\n margin: 8px 0;\n}\n.cc-print-design-chart-data pre {\n max-height: 200px;\n overflow: auto;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-chart-simple {\n margin: 10px 0;\n}\n.cc-print-design-table-data {\n padding: 12px;\n border-bottom: 1px solid var(--pd-border);\n --canvas-react-control-height: 28px;\n}\n.cc-print-design-table-data h4 {\n font-size: var(--pd-primary-font-size, 13px);\n margin: 12px 0;\n}\n.cc-print-design-table-data label:not(.canvas-react-checkbox) {\n display: flex;\n flex-direction: column;\n gap: 6px;\n margin: 10px 0;\n}\n.cc-print-design-compact-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n.cc-print-design-compact-grid > .canvas-react-checkbox {\n grid-column: 1 / -1;\n}\n.cc-print-design-table-data.cc-print-design-compact-grid label:not(.canvas-react-checkbox) {\n min-width: 0;\n gap: 4px;\n margin: 0;\n}\n.cc-print-design-compact-grid .canvas-react-input-number,\n.cc-print-design-compact-grid .canvas-react-color-picker {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-table-column {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n margin-bottom: 8px;\n overflow: hidden;\n}\n.cc-print-design-column-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n min-width: 0;\n}\n.cc-print-design-column-heading > span {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.cc-print-design-column-heading small {\n flex-shrink: 0;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n font-weight: normal;\n}\n.cc-print-design-column-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px;\n}\n.cc-print-design-column-grid > * {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-column-grid > .cc-print-design-column-half {\n grid-column: span 1;\n}\n.cc-print-design-table-data .cc-print-design-column-grid label:not(.canvas-react-checkbox),\n.cc-print-design-column-grid > .cc-print-design-field {\n gap: 4px;\n margin: 0;\n}\n.cc-print-design-column-grid .canvas-react-input-number {\n min-width: 0;\n width: 100%;\n}\n.cc-print-design-column-actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 8px;\n}\n.cc-print-design-column-actions > .canvas-react-button {\n padding: 4px;\n}\n.cc-print-design-table-json {\n margin: 12px 0;\n}\n.cc-print-design-table-json textarea {\n box-sizing: border-box;\n width: 100%;\n min-height: 160px;\n resize: vertical;\n font-size: var(--pd-primary-font-size, 13px);\n margin: 8px 0;\n}\n.cc-print-design-table-row {\n border: 1px solid var(--pd-border);\n border-radius: 6px;\n padding: 8px;\n margin: 8px 0;\n}\n.cc-print-design-table-data pre {\n max-height: 200px;\n overflow: auto;\n font-size: var(--pd-primary-font-size, 13px);\n overscroll-behavior: contain;\n}\n.cc-print-design-table-colors > div {\n border-bottom: 1px solid var(--pd-border);\n padding-bottom: 8px;\n}\n.cc-print-design-layer-controls {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 8px 0;\n}\n.cc-print-design-layer-controls .canvas-react-button {\n padding: 6px;\n}\n.cc-print-design-layer-item {\n position: relative;\n}\n.cc-print-design-layer-drag {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n padding: 4px;\n border: 0;\n background: transparent;\n color: var(--pd-muted);\n cursor: grab;\n}\n.cc-print-design-layer-drag:active {\n cursor: grabbing;\n}\n.cc-print-design-layer-drag:disabled {\n cursor: default;\n opacity: 0.4;\n}\n.cc-print-design-layer-children {\n margin-left: 12px;\n border-left: 1px solid var(--pd-divider);\n padding-left: 3px;\n}\n.cc-print-design-layer-drag {\n touch-action: none;\n}\n.cc-print-design-layer-menu {\n padding: 4px;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-layer-menu button {\n display: flex;\n gap: 8px;\n align-items: center;\n width: 100%;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: var(--pd-text);\n padding: 8px;\n cursor: pointer;\n}\n.cc-print-design-layer-menu button:hover:not(:disabled),\n.cc-print-design-layer-menu button:focus-visible {\n background: var(--pd-selected);\n}\n.cc-print-design-layer-menu button:disabled {\n opacity: 0.4;\n cursor: default;\n}\n.cc-print-design-layer-menu button > span:last-child {\n margin-left: auto;\n color: var(--pd-muted);\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-layer-list {\n user-select: none;\n}\n.cc-print-design-menu-separator {\n height: 1px;\n background: var(--pd-divider);\n margin: 4px 0;\n}\n.cc-print-design-layer-menu button.danger {\n color: var(--pd-danger);\n}\n.cc-print-design-layer-menu button > .cc-print-design-menu-label:last-child {\n margin-left: 0;\n color: inherit;\n font-size: var(--pd-primary-font-size, 13px);\n}\n.cc-print-design-layer-order-row {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n.cc-print-design-layer-order-row > :first-child {\n flex: 1;\n min-width: 0;\n width: 0;\n}\n.cc-print-design-layer-order-row .cc-print-design-layer-controls {\n flex: none;\n flex-wrap: nowrap;\n gap: 2px;\n margin: 0;\n}\n.cc-print-design-alignment-controls {\n display: flex;\n gap: 6px;\n}\n.cc-print-design-alignment-controls .canvas-react-button {\n flex: 1;\n padding: 6px;\n}\n.cc-print-design-alignment-controls .canvas-react-button[aria-pressed=true] {\n color: var(--pd-primary, #2563eb);\n border-color: var(--pd-primary, #2563eb);\n background: var(--pd-selected);\n}\n.cc-print-design-data-fieldset {\n margin: 0;\n padding: 0;\n border: 0;\n min-width: 0;\n}\n.cc-print-design-data-preview {\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n margin: 0;\n}\n.cc-print-design-layer-heading {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n}\n.cc-print-design-layer-heading .cc-print-design-section-title {\n margin: 0;\n}\n.cc-print-design-link {\n border: 0;\n padding: 0;\n color: var(--pd-primary);\n background: transparent;\n cursor: pointer;\n font-size: var(--pd-secondary-font-size, 11px);\n}\n.cc-print-design-link:disabled {\n color: #b8c0cc;\n cursor: not-allowed;\n}\n.cc-print-design-editor .canvas-react-button:hover:not(:disabled) {\n border-color: var(--pd-primary);\n color: var(--pd-primary);\n}\n.cc-print-design-editor .canvas-react-button-primary {\n border-color: var(--pd-primary);\n background: var(--pd-primary);\n color: #fff;\n}\n.cc-print-design-editor .canvas-react-button-primary:hover:not(:disabled) {\n border-color: var(--canvas-react-color-primary-hover);\n background: var(--canvas-react-color-primary-hover);\n color: #fff;\n}\n.cc-print-design-editor .canvas-react-radio input:checked + .canvas-react-radio-mark {\n border-color: var(--pd-primary);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-select-disabled,\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled {\n background: var(--pd-subtle);\n color: var(--pd-muted);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled:hover {\n border-color: var(--pd-border);\n}\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled .canvas-react-input-number-input,\n.cc-print-design-editor[data-theme=dark] .canvas-react-input-number-disabled .canvas-react-input-number-handler:disabled {\n color: var(--pd-muted);\n}\n.cc-print-design-editor .cc-print-design-field > span:first-child,\n.cc-print-design-editor .cc-print-design-settings-field > span:first-child,\n.cc-print-design-editor .cc-print-design-table-data label,\n.cc-print-design-editor .cc-print-design-chart-data label {\n font-size: var(--pd-label-font-size, 12px);\n color: var(--pd-muted);\n}\n.cc-print-design-editor .canvas-react-input,\n.cc-print-design-editor .canvas-react-textarea,\n.cc-print-design-editor .canvas-react-input-number-input {\n font-size: var(--pd-primary-font-size, 13px);\n color: var(--pd-text);\n}\n.cc-print-design-row-settings:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n}\n.cc-print-design-row-settings > * {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-row-settings > .cc-print-design-column-half {\n grid-column: span 1;\n margin: 0;\n gap: 4px;\n}\n.cc-print-design-row-settings .canvas-react-input-number {\n min-width: 0;\n width: 100%;\n}\n.cc-print-design-row-settings .cc-print-design-hint {\n margin: 0;\n}\n.cc-print-design-data-compact {\n padding: 8px;\n}\n.cc-print-design-data-compact .cc-print-design-hint {\n margin: 6px 0;\n}\n.cc-print-design-data-compact .cc-print-design-table-json {\n margin: 6px 0;\n}\n.cc-print-design-data-compact .cc-print-design-table-row {\n padding: 0;\n margin: 6px 0;\n overflow: hidden;\n}\n.cc-print-design-static-row-grid:not([hidden]) {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px;\n}\n.cc-print-design-static-row-grid > * {\n min-width: 0;\n}\n.cc-print-design-static-tasks > strong,\n.cc-print-design-task-dependencies > strong {\n display: block;\n margin: 8px 0 4px;\n}\n.cc-print-design-gantt-connection-title {\n display: block;\n margin: 12px 0 6px;\n}\n.cc-print-design-task-title {\n padding: 8px;\n font-weight: 600;\n}\n.cc-print-design-task-dependencies {\n grid-column: 1 / -1;\n min-width: 0;\n}\n.cc-print-design-task-dependency-row {\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 8px;\n padding: 8px 0;\n border-top: 1px solid #e7edf5;\n}\n.cc-print-design-task-dependency-row > * {\n min-width: 0;\n}\n.cc-print-design-table-data .cc-print-design-static-row-grid label:not(.canvas-react-checkbox) {\n margin: 0;\n gap: 4px;\n overflow-wrap: anywhere;\n}\n.cc-print-design-static-row-grid .canvas-react-input-number {\n width: 100%;\n min-width: 0;\n}\n.cc-print-design-static-row-grid > .cc-print-design-table-json,\n.cc-print-design-static-row-actions {\n grid-column: 1 / -1;\n}\n.cc-print-design-static-row-actions {\n display: flex;\n justify-content: flex-end;\n}\n.cc-print-design-static-row-actions > .canvas-react-button {\n padding: 4px;\n}\n');
8699
9635
 
8700
9636
  // src/styles/scrollbar.css
8701
9637
  styleInject(".cc-print-design-panels .canvas-react-resizable-panel {\n overflow: hidden;\n}\n.cc-print-design-left-panel,\n.cc-print-design-properties,\n.cc-print-design-chart-data pre {\n overscroll-behavior: contain;\n}\n.cc-print-design-editor .cc-print-design-text-editor {\n scrollbar-width: thin;\n overscroll-behavior: contain;\n}\n.cc-print-design-editor .cc-print-design-text-editor::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n.cc-print-design-editor .cc-print-design-text-editor::-webkit-scrollbar-track,\n.cc-print-design-editor .cc-print-design-text-editor::-webkit-scrollbar-corner {\n background: transparent;\n}\n.cc-print-design-editor .cc-print-design-text-editor::-webkit-scrollbar-thumb {\n min-height: 32px;\n border: 2px solid transparent;\n border-radius: 999px;\n background: #aeb4bd;\n background-clip: content-box;\n}\n.cc-print-design-editor .cc-print-design-text-editor::-webkit-scrollbar-thumb:hover {\n background: #8f98a5;\n background-clip: content-box;\n}\n");
@@ -8777,7 +9713,13 @@ var ReactPrintDesign = forwardRef(
8777
9713
  const [document2, setDocument] = useState(
8778
9714
  () => documentProp ?? createPrintDesignDocument()
8779
9715
  );
8780
- const preview = usePrintPreviewPages(document2, mockRecords, previewOpen);
9716
+ const previewLoader = importedMockRecords ? void 0 : props.loadPreviewData;
9717
+ const preview = usePrintPreviewPages(
9718
+ document2,
9719
+ mockRecords,
9720
+ previewOpen,
9721
+ previewLoader
9722
+ );
8781
9723
  const previewPage = previewOpen ? preview.pages[previewIndex] : void 0;
8782
9724
  useEffect(() => {
8783
9725
  setPreviewIndex(
@@ -8796,7 +9738,10 @@ var ReactPrintDesign = forwardRef(
8796
9738
  const pdfDragRef = useRef(null);
8797
9739
  const pngDragRef = useRef(null);
8798
9740
  const savedSnapshotRef = useRef(JSON.stringify(documentProp ?? document2));
8799
- const hasUnsavedChanges = () => JSON.stringify(instanceRef.current?.getDocument() ?? document2) !== savedSnapshotRef.current;
9741
+ const tourSourceRef = useRef(null);
9742
+ const hasUnsavedChanges = () => JSON.stringify(
9743
+ tourSourceRef.current ?? instanceRef.current?.getDocument() ?? document2
9744
+ ) !== savedSnapshotRef.current;
8800
9745
  const [discardConfirmOpen, setDiscardConfirmOpen] = useState(false);
8801
9746
  const discardResolverRef = useRef(
8802
9747
  null
@@ -8839,6 +9784,80 @@ var ReactPrintDesign = forwardRef(
8839
9784
  elementIds: []
8840
9785
  });
8841
9786
  const [activePageId, setActivePageId] = useState(document2.pages[0].id);
9787
+ const [tourOpen, setTourOpen] = useState(false);
9788
+ const [tourIndex, setTourIndex] = useState(0);
9789
+ const [tourPlaying, setTourPlaying] = useState(false);
9790
+ const [tourSource, setTourSource] = useState(
9791
+ null
9792
+ );
9793
+ const tourDocument = tourSource ?? document2;
9794
+ const tourSteps = useMemo(
9795
+ () => createPrintDesignTourSteps(tourDocument),
9796
+ [tourDocument]
9797
+ );
9798
+ const tourDisplaySteps = useMemo(
9799
+ () => tourSteps.map((step) => {
9800
+ if (!step.elementId) return step;
9801
+ if (step.operation === "add")
9802
+ return {
9803
+ ...step,
9804
+ target: () => instanceRef.current?.getElementClientRect(step.elementId) ?? null
9805
+ };
9806
+ if (step.operation === "layer")
9807
+ return {
9808
+ ...step,
9809
+ target: () => [
9810
+ ...globalThis.document.querySelectorAll(
9811
+ "[data-tour-element-id]"
9812
+ )
9813
+ ].find(
9814
+ (node) => node.dataset.tourElementId === step.elementId
9815
+ ) ?? globalThis.document.querySelector(
9816
+ ".cc-print-design-left-panel"
9817
+ )
9818
+ };
9819
+ return step;
9820
+ }),
9821
+ [tourSteps]
9822
+ );
9823
+ const tourHighlightTarget = useMemo(() => {
9824
+ const step = tourSteps[tourIndex];
9825
+ if (!step?.elementId || step.operation !== "field" && step.operation !== "layer")
9826
+ return void 0;
9827
+ return () => instanceRef.current?.getElementClientRect(step.elementId) ?? null;
9828
+ }, [tourIndex, tourSteps]);
9829
+ const focusTourStep = (index) => {
9830
+ const step = tourSteps[index];
9831
+ const instance = instanceRef.current;
9832
+ const source = tourSourceRef.current;
9833
+ if (!step || !instance || !source) return;
9834
+ instance.showTemporaryDocument(
9835
+ createPrintDesignTourDocument(source, step),
9836
+ step.pageId,
9837
+ step.operation === "add" || step.operation === "field" || step.operation === "layer" ? step.elementId : void 0
9838
+ );
9839
+ setActiveTab(
9840
+ step.operation === "page" ? "pages" : step.operation === "layer" ? "layers" : "elements"
9841
+ );
9842
+ setMobileView(
9843
+ step.operation === "field" ? "properties" : step.operation === "add" ? "canvas" : "panel"
9844
+ );
9845
+ setActivePageId(instance.getActivePageId());
9846
+ setSelection(instance.getSelection());
9847
+ setTourIndex(index);
9848
+ };
9849
+ const closeTour = () => {
9850
+ setTourOpen(false);
9851
+ setTourPlaying(false);
9852
+ const instance = instanceRef.current;
9853
+ instance?.restoreTemporaryDocument();
9854
+ tourSourceRef.current = null;
9855
+ setTourSource(null);
9856
+ if (instance) {
9857
+ setActivePageId(instance.getActivePageId());
9858
+ setSelection(instance.getSelection());
9859
+ }
9860
+ };
8842
9861
  const [preferences, setPreferences] = useState({
8843
9862
  ...defaultEditorPreferences,
8844
9863
  displayUnit: props.displayUnit ?? "mm"
@@ -8923,46 +9942,75 @@ var ReactPrintDesign = forwardRef(
8923
9942
  setPendingGroup(null);
8924
9943
  };
8925
9944
  const exportFileName = (format) => exportFileNames[format] ?? `${document2.name || "print-design"}.${format === "png" ? "zip" : format}`;
9945
+ const outputTaskRef = useRef(null);
9946
+ useEffect(() => () => outputTaskRef.current?.abort(), []);
9947
+ const resolveOutputSource = async () => {
9948
+ if (!previewLoader) return { document: document2, data: currentData };
9949
+ if (previewOpen && !preview.loading && !preview.error && preview.source)
9950
+ return preview.source;
9951
+ outputTaskRef.current?.abort();
9952
+ const controller = new AbortController();
9953
+ outputTaskRef.current = controller;
9954
+ const source = await previewLoader(document2, {
9955
+ signal: controller.signal
9956
+ });
9957
+ controller.signal.throwIfAborted();
9958
+ return source;
9959
+ };
8926
9960
  const confirmExport = async (fileName) => {
8927
9961
  if (!exportFormat) return;
9962
+ const source = exportFormat === "json" ? { document: document2, data: currentData } : await resolveOutputSource();
8928
9963
  if (exportFormat === "json") downloadJson(document2, fileName);
8929
9964
  if (exportFormat === "html")
8930
- downloadHtml(document2, currentData, fileName);
9965
+ downloadHtml(source.document, source.data, fileName);
8931
9966
  if (exportFormat === "png")
8932
- await downloadPngPages(document2, mockRecords, fileName);
9967
+ await downloadPngPages(
9968
+ source.document,
9969
+ previewLoader ? [source.data] : mockRecords,
9970
+ fileName
9971
+ );
8933
9972
  if (exportFormat === "pdf")
8934
- await downloadPdf(document2, currentData, fileName);
9973
+ await downloadPdf(source.document, source.data, fileName);
8935
9974
  setExportFileNames((current) => ({
8936
9975
  ...current,
8937
9976
  [exportFormat]: fileName
8938
9977
  }));
8939
9978
  setExportFormat(null);
8940
9979
  };
9980
+ const dragReady = !previewLoader || previewOpen && !preview.loading && !preview.error && preview.source != null;
9981
+ const dragDocument = previewLoader && preview.source ? preview.source.document : document2;
9982
+ const dragData = previewLoader && preview.source ? preview.source.data : currentData;
9983
+ const dragRecords = useMemo(
9984
+ () => previewLoader ? [dragData] : mockRecords,
9985
+ [previewLoader, dragData, mockRecords]
9986
+ );
8941
9987
  const preparePdfDrag = () => {
8942
- if (pdfDragRef.current?.document === document2 && pdfDragRef.current.data === currentData)
9988
+ if (!dragReady) return;
9989
+ if (pdfDragRef.current?.document === dragDocument && pdfDragRef.current.data === dragData)
8943
9990
  return;
8944
9991
  const entry = {
8945
- document: document2,
8946
- data: currentData,
9992
+ document: dragDocument,
9993
+ data: dragData,
8947
9994
  blob: void 0
8948
9995
  };
8949
9996
  pdfDragRef.current = entry;
8950
- void createPdfBlob(document2, currentData).then((blob) => {
9997
+ void createPdfBlob(dragDocument, dragData).then((blob) => {
8951
9998
  entry.blob = blob;
8952
9999
  }).catch(() => {
8953
10000
  if (pdfDragRef.current === entry) pdfDragRef.current = null;
8954
10001
  });
8955
10002
  };
8956
10003
  const preparePngDrag = () => {
8957
- if (pngDragRef.current?.document === document2 && pngDragRef.current.records === mockRecords)
10004
+ if (!dragReady) return;
10005
+ if (pngDragRef.current?.document === dragDocument && pngDragRef.current.records === dragRecords)
8958
10006
  return;
8959
10007
  const entry = {
8960
- document: document2,
8961
- records: mockRecords,
10008
+ document: dragDocument,
10009
+ records: dragRecords,
8962
10010
  blob: void 0
8963
10011
  };
8964
10012
  pngDragRef.current = entry;
8965
- void createPngArchiveBlob(document2, mockRecords).then((blob) => {
10013
+ void createPngArchiveBlob(dragDocument, dragRecords).then((blob) => {
8966
10014
  entry.blob = blob;
8967
10015
  }).catch(() => {
8968
10016
  if (pngDragRef.current === entry) pngDragRef.current = null;
@@ -9191,7 +10239,7 @@ var ReactPrintDesign = forwardRef(
9191
10239
  onChange: (next) => {
9192
10240
  setDocument(next);
9193
10241
  setRevision((revision) => revision + 1);
9194
- callbacksRef.current.onChange?.(next);
10242
+ if (!tourSourceRef.current) callbacksRef.current.onChange?.(next);
9195
10243
  },
9196
10244
  onSelectionChange: (next) => {
9197
10245
  setSelection(next);
@@ -9328,6 +10376,7 @@ var ReactPrintDesign = forwardRef(
9328
10376
  };
9329
10377
  const selectTemplate = async (item, skipConfirm = false) => {
9330
10378
  if (!skipConfirm && !await confirmDiscard()) return;
10379
+ closeTour();
9331
10380
  instanceRef.current?.setDocument(item.document);
9332
10381
  savedSnapshotRef.current = JSON.stringify(item.document);
9333
10382
  setSelectedTemplateId(item.templateId);
@@ -9336,6 +10385,7 @@ var ReactPrintDesign = forwardRef(
9336
10385
  };
9337
10386
  const selectDefaultTemplate = async (item, skipConfirm = false) => {
9338
10387
  if (!skipConfirm && !await confirmDiscard()) return;
10388
+ closeTour();
9339
10389
  instanceRef.current?.setDocument(item);
9340
10390
  savedSnapshotRef.current = JSON.stringify(item);
9341
10391
  setSelectedTemplateId(null);
@@ -9537,6 +10587,7 @@ var ReactPrintDesign = forwardRef(
9537
10587
  );
9538
10588
  };
9539
10589
  const handleEditorKeyDown = (event) => {
10590
+ if (tourOpen) return;
9540
10591
  if ((event.ctrlKey || event.metaKey) && event.key.toLowerCase() === "s") {
9541
10592
  event.preventDefault();
9542
10593
  void saveTemplate();
@@ -9652,7 +10703,7 @@ var ReactPrintDesign = forwardRef(
9652
10703
  onApplyPreferences: applyPreferences,
9653
10704
  onResetPreferences: resetEditorSettings,
9654
10705
  readonly,
9655
- contentReadonly: editingReadonly,
10706
+ contentReadonly: editingReadonly && !tourOpen,
9656
10707
  settings: {
9657
10708
  ...interactionSettings,
9658
10709
  showRulers,
@@ -9741,13 +10792,30 @@ var ReactPrintDesign = forwardRef(
9741
10792
  if (event.target.closest("textarea,input"))
9742
10793
  return;
9743
10794
  event.preventDefault();
10795
+ const selector = instanceRef.current?.tableSelectorAtClientPoint(
10796
+ event.clientX,
10797
+ event.clientY
10798
+ );
9744
10799
  mutate(
9745
- (instance) => instance.selectAtClientPoint(
10800
+ (instance) => selector ? instance.selectTableSelector(
10801
+ selector.elementId,
10802
+ selector.kind,
10803
+ selector.index,
10804
+ selector.area
10805
+ ) : instance.selectAtClientPoint(
9746
10806
  event.clientX,
9747
10807
  event.clientY
9748
10808
  )
9749
10809
  );
9750
- setContextMenu({ x: event.clientX, y: event.clientY });
10810
+ setContextMenu({
10811
+ x: event.clientX,
10812
+ y: event.clientY,
10813
+ tableSelector: selector,
10814
+ tableCell: instanceRef.current?.tableCellAtClientPoint(
10815
+ event.clientX,
10816
+ event.clientY
10817
+ )
10818
+ });
9751
10819
  },
9752
10820
  onDragOver: handleCanvasDragOver,
9753
10821
  onDrop: handleCanvasDrop
@@ -9766,7 +10834,7 @@ var ReactPrintDesign = forwardRef(
9766
10834
  document: document2,
9767
10835
  version: selectedVersion,
9768
10836
  invalid: selectedInvalid,
9769
- readonly: editingReadonly || previewOpen,
10837
+ readonly: editingReadonly && !tourOpen || previewOpen,
9770
10838
  onChange: (patch) => void updateTemplateMetadata(patch)
9771
10839
  }
9772
10840
  ) : /* @__PURE__ */ jsx(
@@ -9777,6 +10845,34 @@ var ReactPrintDesign = forwardRef(
9777
10845
  page: activePage,
9778
10846
  element: activeTab === "pages" ? void 0 : selectedElement,
9779
10847
  selectedIds: activeTab === "pages" ? [] : selection.elementIds,
10848
+ tableCellSelection: instanceRef.current?.getTableCellSelection(),
10849
+ onMergeSelectedTableCells: () => mutate((instance) => {
10850
+ const range = instance.getTableCellSelection();
10851
+ if (!range) return;
10852
+ const row = Math.min(range.startRow, range.endRow);
10853
+ const column = Math.min(
10854
+ range.startColumn,
10855
+ range.endColumn
10856
+ );
10857
+ const rows = Math.abs(range.endRow - range.startRow) + 1;
10858
+ const columns = Math.abs(range.endColumn - range.startColumn) + 1;
10859
+ if (range.area === "header")
10860
+ instance.mergeTableHeaderCell(
10861
+ range.elementId,
10862
+ row,
10863
+ column,
10864
+ rows,
10865
+ columns
10866
+ );
10867
+ else
10868
+ instance.mergeTableCell(
10869
+ range.elementId,
10870
+ row,
10871
+ column,
10872
+ rows,
10873
+ columns
10874
+ );
10875
+ }),
9780
10876
  onAlign: (align) => mutate((instance) => instance.alignSelection(align)),
9781
10877
  onGroupRename: (id, name) => mutate((instance) => instance.renameGroup(id, name)),
9782
10878
  onSaveGroup: requestSaveGroup,
@@ -9786,7 +10882,7 @@ var ReactPrintDesign = forwardRef(
9786
10882
  (instance) => instance.setElementLayer(selectedElement.id, index)
9787
10883
  ),
9788
10884
  guide: activeTab === "pages" ? void 0 : selection.guide,
9789
- readonly: editingReadonly || previewOpen,
10885
+ readonly: editingReadonly && !tourOpen || previewOpen,
9790
10886
  settings: { ...interactionSettings, showGuides },
9791
10887
  onSettingsChange: changeSettings,
9792
10888
  onGuidePositionChange: (position) => selection.guide && mutate(
@@ -9823,10 +10919,30 @@ var ReactPrintDesign = forwardRef(
9823
10919
  if (event.target.closest("textarea,input"))
9824
10920
  return;
9825
10921
  event.preventDefault();
10922
+ const selector = instanceRef.current?.tableSelectorAtClientPoint(
10923
+ event.clientX,
10924
+ event.clientY
10925
+ );
9826
10926
  mutate(
9827
- (instance) => instance.selectAtClientPoint(event.clientX, event.clientY)
10927
+ (instance) => selector ? instance.selectTableSelector(
10928
+ selector.elementId,
10929
+ selector.kind,
10930
+ selector.index,
10931
+ selector.area
10932
+ ) : instance.selectAtClientPoint(
10933
+ event.clientX,
10934
+ event.clientY
10935
+ )
9828
10936
  );
9829
- setContextMenu({ x: event.clientX, y: event.clientY });
10937
+ setContextMenu({
10938
+ x: event.clientX,
10939
+ y: event.clientY,
10940
+ tableSelector: selector,
10941
+ tableCell: instanceRef.current?.tableCellAtClientPoint(
10942
+ event.clientX,
10943
+ event.clientY
10944
+ )
10945
+ });
9830
10946
  },
9831
10947
  onDragOver: handleCanvasDragOver,
9832
10948
  onDrop: handleCanvasDrop
@@ -9860,7 +10976,9 @@ var ReactPrintDesign = forwardRef(
9860
10976
  selection.elementIds,
9861
10977
  editingReadonly,
9862
10978
  instanceRef.current,
9863
- requestSaveGroup
10979
+ requestSaveGroup,
10980
+ contextMenu?.tableCell,
10981
+ contextMenu?.tableSelector
9864
10982
  ),
9865
10983
  onAction: (item) => {
9866
10984
  if (item.key === "saveCustomComponent") {
@@ -9871,6 +10989,20 @@ var ReactPrintDesign = forwardRef(
9871
10989
  onClose: () => setContextMenu(null)
9872
10990
  }
9873
10991
  ),
10992
+ /* @__PURE__ */ jsx(
10993
+ ReactTour,
10994
+ {
10995
+ open: tourOpen,
10996
+ steps: tourDisplaySteps,
10997
+ current: tourIndex,
10998
+ highlightTarget: tourHighlightTarget,
10999
+ onChange: focusTourStep,
11000
+ onClose: closeTour,
11001
+ playing: tourPlaying,
11002
+ onPlayingChange: setTourPlaying,
11003
+ interval: 4500
11004
+ }
11005
+ ),
9874
11006
  /* @__PURE__ */ jsx(
9875
11007
  ReactPopconfirm,
9876
11008
  {
@@ -10080,7 +11212,7 @@ var ReactPrintDesign = forwardRef(
10080
11212
  onClick: () => setPreviewIndex((index) => Math.max(0, index - 1))
10081
11213
  }
10082
11214
  ),
10083
- /* @__PURE__ */ jsx("span", { role: "status", children: preview.error ? preview.error : `${preview.pages.length ? previewIndex + 1 : 0} / ${preview.pages.length}${preview.processed < mockRecords.length ? " \xB7 \u751F\u6210\u4E2D" : ""}` }),
11215
+ /* @__PURE__ */ jsx("span", { role: "status", children: preview.error ? preview.error : `${preview.pages.length ? previewIndex + 1 : 0} / ${preview.pages.length}${preview.loading ? ` \xB7 ${preview.progress || "\u751F\u6210\u4E2D"}` : ""}` }),
10084
11216
  /* @__PURE__ */ jsx(
10085
11217
  ReactButton,
10086
11218
  {
@@ -10153,10 +11285,10 @@ var ReactPrintDesign = forwardRef(
10153
11285
  {
10154
11286
  key: "html",
10155
11287
  label: "HTML",
10156
- draggable: true,
11288
+ draggable: dragReady,
10157
11289
  onDragStart: (event) => setExportDragData(
10158
11290
  event.dataTransfer,
10159
- createHtmlBlob(document2, currentData),
11291
+ createHtmlBlob(dragDocument, dragData),
10160
11292
  exportFileName("html")
10161
11293
  )
10162
11294
  },
@@ -10164,11 +11296,11 @@ var ReactPrintDesign = forwardRef(
10164
11296
  key: "png",
10165
11297
  label: "PNG \xB7 \u5168\u90E8\u9875 ZIP",
10166
11298
  description: "\u6309 Mock \u6570\u636E\u9010\u9875\u5BFC\u51FA",
10167
- draggable: true,
11299
+ draggable: dragReady,
10168
11300
  onPointerEnter: preparePngDrag,
10169
11301
  onDragStart: (event) => {
10170
11302
  const ready = pngDragRef.current;
10171
- if (ready?.document === document2 && ready.records === mockRecords && ready.blob) {
11303
+ if (ready?.document === dragDocument && ready.records === dragRecords && ready.blob) {
10172
11304
  setExportDragData(
10173
11305
  event.dataTransfer,
10174
11306
  ready.blob,
@@ -10185,11 +11317,11 @@ var ReactPrintDesign = forwardRef(
10185
11317
  key: "pdf",
10186
11318
  label: "PDF \xB7 \u5B9E\u9A8C\u6027",
10187
11319
  description: "\u56FE\u7247\u5F0F\u9875\u9762\uFF0C\u6587\u5B57\u6682\u4E0D\u53EF\u9009\u4E2D",
10188
- draggable: true,
11320
+ draggable: dragReady,
10189
11321
  onPointerEnter: preparePdfDrag,
10190
11322
  onDragStart: (event) => {
10191
11323
  const ready = pdfDragRef.current;
10192
- if (ready?.document === document2 && ready.data === currentData && ready.blob) {
11324
+ if (ready?.document === dragDocument && ready.data === dragData && ready.blob) {
10193
11325
  setExportDragData(
10194
11326
  event.dataTransfer,
10195
11327
  ready.blob,
@@ -10215,9 +11347,32 @@ var ReactPrintDesign = forwardRef(
10215
11347
  title: "\u6253\u5370",
10216
11348
  "aria-label": "\u6253\u5370",
10217
11349
  icon: /* @__PURE__ */ jsx(ReactPrinterOutlined, { "aria-hidden": "true" }),
10218
- onClick: () => mutate((instance) => {
10219
- instance.printDocument();
10220
- })
11350
+ onClick: () => {
11351
+ if (!previewLoader) {
11352
+ mutate((instance) => {
11353
+ instance.printDocument();
11354
+ });
11355
+ return;
11356
+ }
11357
+ const popup = window.open("", "_blank");
11358
+ if (!popup) return;
11359
+ popup.document.body.textContent = "\u6B63\u5728\u51C6\u5907\u6253\u5370\u6570\u636E\u2026";
11360
+ void resolveOutputSource().then((source) => {
11361
+ if (!popup.closed)
11362
+ printPrintDesignHtml(
11363
+ popup,
11364
+ transformPrintDesignToHtml(source.document, {
11365
+ data: source.data
11366
+ })
11367
+ );
11368
+ }).catch((cause) => {
11369
+ popup.close();
11370
+ if (!(cause instanceof Error && cause.name === "AbortError"))
11371
+ window.alert(
11372
+ cause instanceof Error ? cause.message : "\u51C6\u5907\u6253\u5370\u6570\u636E\u5931\u8D25"
11373
+ );
11374
+ });
11375
+ }
10221
11376
  }
10222
11377
  ),
10223
11378
  /* @__PURE__ */ jsx(
@@ -10234,6 +11389,30 @@ var ReactPrintDesign = forwardRef(
10234
11389
  }))
10235
11390
  }
10236
11391
  ),
11392
+ /* @__PURE__ */ jsx(
11393
+ ReactButton,
11394
+ {
11395
+ title: "\u6F14\u793A\u6A21\u677F\u642D\u5EFA\u64CD\u4F5C",
11396
+ "aria-label": "\u6F14\u793A\u6A21\u677F\u642D\u5EFA\u64CD\u4F5C",
11397
+ icon: /* @__PURE__ */ jsx(ReactPlayCircleOutlined, { "aria-hidden": "true" }),
11398
+ onClick: () => {
11399
+ const instance = instanceRef.current;
11400
+ if (!instance) return;
11401
+ const source = instance.getDocument();
11402
+ const first = createPrintDesignTourSteps(source)[0];
11403
+ setPreviewOpen(false);
11404
+ setContextMenu(null);
11405
+ tourSourceRef.current = source;
11406
+ setTourSource(source);
11407
+ instance.showTemporaryDocument(
11408
+ createPrintDesignTourDocument(source, first)
11409
+ );
11410
+ setTourIndex(0);
11411
+ setTourPlaying(true);
11412
+ setTourOpen(true);
11413
+ }
11414
+ }
11415
+ ),
10237
11416
  props.showFullscreenButton !== false || props.onClose ? /* @__PURE__ */ jsx("span", { className: "cc-print-design-toolbar-separator" }) : null,
10238
11417
  props.showFullscreenButton !== false ? /* @__PURE__ */ jsx(
10239
11418
  ReactButton,