@bit-sun/business-component 4.2.0-alpha.33-wyl → 4.2.0-alpha.35-wyl

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.
@@ -9,6 +9,13 @@ export interface RangeCopyResult {
9
9
  rowCount: number;
10
10
  colCount: number;
11
11
  }
12
+ /**
13
+ * 单元格取文本:用 textContent(不依赖布局,避免逐格 innerText 反复触发布局校验),
14
+ * 去掉零宽字符、把不换行空格还原成空格,并把会破坏 TSV 结构的制表符与换行压成空格。
15
+ */
16
+ /** 文本归一:去零宽字符、NBSP 还原空格、制表符与换行压成空格 */
17
+ export declare const normalizeText: (value?: string | null) => string;
18
+ export declare const normalizeCellText: (cell?: HTMLTableCellElement) => string;
12
19
  /** 选区里真正会被复制的列(按列序);勾选列/操作列等被排除的列不占位 */
13
20
  export declare const getIncludedCols: (colStart: number, colEnd: number, excludeCols?: Set<number>) => number[];
14
21
  export declare const buildRangeCopy: (rows: HTMLTableRowElement[], colStart: number, colEnd: number, excludeCols?: Set<number>) => RangeCopyResult;
@@ -0,0 +1,15 @@
1
+ /// <reference types="react" />
2
+ export interface UseVirtualRangeCopyOptions {
3
+ /** 容器 ref(与经典路径共用同一个 DOM 容器) */
4
+ containerRef: React.RefObject<HTMLElement>;
5
+ /** 是否启用;BsSulaQueryTable 按 rangeCopy / isVirtualTable 决定 */
6
+ enabled?: boolean;
7
+ excludeTitles?: string[];
8
+ autoCopy?: boolean;
9
+ }
10
+ /**
11
+ * 虚拟滚动表(rc-virtual-list 表体)的框选复制。
12
+ * 只渲染可视区附近的行,所以拖拽/自动滚动过程中"边滚边采",松手时按区间拼 TSV,
13
+ * 并对没被渲染到的行如实提示(不假装完整)。
14
+ */
15
+ export declare const useVirtualRangeCopy: (options: UseVirtualRangeCopyOptions) => void;
@@ -0,0 +1,26 @@
1
+ export interface RenderedRow {
2
+ row: HTMLElement;
3
+ /** 行内容坐标:相对 holder-inner 顶部的像素偏移 */
4
+ offset: number;
5
+ cells: HTMLElement[];
6
+ }
7
+ export interface VirtualParts {
8
+ inner: HTMLElement;
9
+ holder: HTMLElement;
10
+ }
11
+ /** 是否虚拟表体:没有常规 tbody,但存在 rc-virtual-list 的渲染区 */
12
+ export declare const isVirtualBody: (container: HTMLElement | null) => boolean;
13
+ export declare const getVirtualParts: (container: HTMLElement | null) => VirtualParts | null;
14
+ /** 收集当前渲染出来的行(按偏移升序);未布局的行(高度 0)跳过 */
15
+ export declare const collectRenderedRows: (inner: HTMLElement) => RenderedRow[];
16
+ /** 行高估算:优先取相邻行偏移差的中位数,退化到行自身高度 */
17
+ export declare const estimateRowHeight: (rows: RenderedRow[]) => number;
18
+ export interface VirtualCopyResult {
19
+ text: string;
20
+ rowCount: number;
21
+ colCount: number;
22
+ /** 区间内没有被渲染到的行数(按行高估算),> 0 时调用方必须如实提示 */
23
+ missingRows: number;
24
+ }
25
+ /** 按偏移区间 + 列区间,用已采集的行拼 TSV */
26
+ export declare const buildVirtualCopy: (harvest: Map<number, string[]>, fromOffset: number, toOffset: number, colStart: number, colEnd: number, excludeCols: Set<number>, rowHeight: number) => VirtualCopyResult;
package/dist/index.esm.js CHANGED
@@ -19998,6 +19998,10 @@ var DATA_ROW_SELECTOR = 'tr.ant-table-row';
19998
19998
  * 单元格取文本:用 textContent(不依赖布局,避免逐格 innerText 反复触发布局校验),
19999
19999
  * 去掉零宽字符、把不换行空格还原成空格,并把会破坏 TSV 结构的制表符与换行压成空格。
20000
20000
  */
20001
+ /** 文本归一:去零宽字符、NBSP 还原空格、制表符与换行压成空格 */
20002
+ var normalizeText = function normalizeText(value) {
20003
+ return (value || '').replace(/\u200b/g, '').replace(/\u00a0/g, ' ').replace(/[\t\r\n]+/g, ' ').replace(/\s{2,}/g, ' ').trim();
20004
+ };
20001
20005
  var normalizeCellText = function normalizeCellText(cell) {
20002
20006
  if (!cell) return '';
20003
20007
  return (cell.textContent || '').replace(/\u200b/g, '').replace(/\u00a0/g, ' ').replace(/[\t\r\n]+/g, ' ').replace(/\s{2,}/g, ' ').trim();
@@ -20049,7 +20053,7 @@ var resolveExcludeCols = function resolveExcludeCols(tbody, titles) {
20049
20053
  return excludeCols;
20050
20054
  };
20051
20055
 
20052
- var css_248z$k = ".bs-range-copy tbody.ant-table-tbody > tr.ant-table-row > td.ant-table-cell:not(.ant-table-cell-fix-right) {\n cursor: cell;\n}\n.bs-range-copy .ant-table-body {\n position: relative;\n}\n.bs-range-copy__overlay {\n position: absolute;\n z-index: 1;\n display: none;\n box-sizing: border-box;\n pointer-events: none;\n background: rgba(24, 144, 255, 0.12);\n border: 1px solid rgba(24, 144, 255, 0.55);\n}\n";
20056
+ var css_248z$k = ".bs-range-copy tbody.ant-table-tbody > tr.ant-table-row > td.ant-table-cell:not(.ant-table-cell-fix-right) {\n cursor: cell;\n}\n.bs-range-copy .ant-table-body,\n.bs-range-copy .rc-virtual-list-holder {\n position: relative;\n}\n.bs-range-copy__overlay {\n position: absolute;\n z-index: 5;\n display: none;\n box-sizing: border-box;\n pointer-events: none;\n background: rgba(24, 144, 255, 0.12);\n border: 1px solid rgba(24, 144, 255, 0.55);\n}\n";
20053
20057
  styleInject(css_248z$k);
20054
20058
 
20055
20059
  var CELL_SELECTOR = 'td.ant-table-cell';
@@ -20465,6 +20469,432 @@ var useRangeCopy = function useRangeCopy(options) {
20465
20469
  return containerRef;
20466
20470
  };
20467
20471
 
20472
+ /** 是否虚拟表体:没有常规 tbody,但存在 rc-virtual-list 的渲染区 */
20473
+ var isVirtualBody = function isVirtualBody(container) {
20474
+ return !!container && !container.querySelector('tbody.ant-table-tbody') && !!container.querySelector('.rc-virtual-list-holder-inner');
20475
+ };
20476
+ var getVirtualParts = function getVirtualParts(container) {
20477
+ if (!container) return null;
20478
+ var inner = container.querySelector('.rc-virtual-list-holder-inner');
20479
+ if (!inner) return null;
20480
+ var holder = inner.closest('.rc-virtual-list-holder') || inner.parentElement;
20481
+ if (!holder) return null;
20482
+ return {
20483
+ inner: inner,
20484
+ holder: holder
20485
+ };
20486
+ };
20487
+ /** 收集当前渲染出来的行(按偏移升序);未布局的行(高度 0)跳过 */
20488
+ var collectRenderedRows = function collectRenderedRows(inner) {
20489
+ var innerTop = inner.getBoundingClientRect().top;
20490
+ var rows = [];
20491
+ Array.from(inner.children).forEach(function (node) {
20492
+ var row = node;
20493
+ var rect = row.getBoundingClientRect();
20494
+ if (rect.height <= 0) return;
20495
+ var cells = Array.from(row.children);
20496
+ if (!cells.length) return;
20497
+ rows.push({
20498
+ row: row,
20499
+ offset: Math.round(rect.top - innerTop),
20500
+ cells: cells
20501
+ });
20502
+ });
20503
+ return rows.sort(function (a, b) {
20504
+ return a.offset - b.offset;
20505
+ });
20506
+ };
20507
+ /** 行高估算:优先取相邻行偏移差的中位数,退化到行自身高度 */
20508
+ var estimateRowHeight = function estimateRowHeight(rows) {
20509
+ if (!rows.length) return 0;
20510
+ var deltas = [];
20511
+ for (var i = 1; i < rows.length; i += 1) {
20512
+ var delta = rows[i].offset - rows[i - 1].offset;
20513
+ if (delta > 0) deltas.push(delta);
20514
+ }
20515
+ if (deltas.length) {
20516
+ deltas.sort(function (a, b) {
20517
+ return a - b;
20518
+ });
20519
+ var mid = deltas[Math.floor(deltas.length / 2)];
20520
+ if (mid > 0) return mid;
20521
+ }
20522
+ return Math.round(rows[0].row.getBoundingClientRect().height) || 0;
20523
+ };
20524
+ /** 按偏移区间 + 列区间,用已采集的行拼 TSV */
20525
+ var buildVirtualCopy = function buildVirtualCopy(harvest, fromOffset, toOffset, colStart, colEnd, excludeCols, rowHeight) {
20526
+ var from = Math.min(fromOffset, toOffset);
20527
+ var to = Math.max(fromOffset, toOffset);
20528
+ var includedCols = getIncludedCols(colStart, colEnd, excludeCols);
20529
+ var picked = Array.from(harvest.entries()).filter(function (_ref) {
20530
+ var _ref2 = _slicedToArray(_ref, 1),
20531
+ offset = _ref2[0];
20532
+ return offset >= from && offset <= to;
20533
+ }).sort(function (a, b) {
20534
+ return a[0] - b[0];
20535
+ });
20536
+ var text = picked.map(function (_ref3) {
20537
+ var _ref4 = _slicedToArray(_ref3, 2),
20538
+ cells = _ref4[1];
20539
+ return includedCols.map(function (col) {
20540
+ return normalizeText(cells[col]);
20541
+ }).join('\t');
20542
+ }).join('\r\n');
20543
+ var expected = rowHeight > 0 ? Math.floor((to - from) / rowHeight) + 1 : picked.length;
20544
+ return {
20545
+ text: text,
20546
+ rowCount: picked.length,
20547
+ colCount: includedCols.length,
20548
+ missingRows: Math.max(0, expected - picked.length)
20549
+ };
20550
+ };
20551
+
20552
+ // 与经典路径保持同一套门控语义:单击不建立选区、mousedown 不做 preventDefault、
20553
+ // 只有"指针挪到别的行/列"(拖拽)或 Shift+点击才真正建立选区。
20554
+ var IGNORE_TARGET_SELECTOR$1 = 'input, textarea, select, [contenteditable="true"]';
20555
+ var DEFAULT_EXCLUDE_TITLES$1 = ['操作'];
20556
+ var EDGE_BAND$1 = 36;
20557
+ var MAX_SCROLL_STEP$1 = 24;
20558
+ /**
20559
+ * 虚拟滚动表(rc-virtual-list 表体)的框选复制。
20560
+ * 只渲染可视区附近的行,所以拖拽/自动滚动过程中"边滚边采",松手时按区间拼 TSV,
20561
+ * 并对没被渲染到的行如实提示(不假装完整)。
20562
+ */
20563
+ var useVirtualRangeCopy = function useVirtualRangeCopy(options) {
20564
+ var optionsRef = useRef(options);
20565
+ optionsRef.current = options;
20566
+ var enabled = (options === null || options === void 0 ? void 0 : options.enabled) !== false;
20567
+ useEffect(function () {
20568
+ var _optionsRef$current, _optionsRef$current$c;
20569
+ if (!enabled) return undefined;
20570
+ var container = (_optionsRef$current = optionsRef.current) === null || _optionsRef$current === void 0 ? void 0 : (_optionsRef$current$c = _optionsRef$current.containerRef) === null || _optionsRef$current$c === void 0 ? void 0 : _optionsRef$current$c.current;
20571
+ if (!container) return undefined;
20572
+ var overlay = document.createElement('div');
20573
+ overlay.className = 'bs-range-copy__overlay';
20574
+ var pressed = false;
20575
+ var dragging = false;
20576
+ var suppressClick = false;
20577
+ var rafId = 0;
20578
+ var autoScrollId = 0;
20579
+ var pointerX = 0;
20580
+ var pointerY = 0;
20581
+ var stepX = 0;
20582
+ var stepY = 0;
20583
+ var anchor = null;
20584
+ var selection = null;
20585
+ var hideOverlay = function hideOverlay() {
20586
+ overlay.style.display = 'none';
20587
+ };
20588
+ var clearSelection = function clearSelection() {
20589
+ selection = null;
20590
+ anchor = null;
20591
+ pressed = false;
20592
+ dragging = false;
20593
+ suppressClick = false;
20594
+ stopAutoScroll();
20595
+ hideOverlay();
20596
+ };
20597
+ var stopAutoScroll = function stopAutoScroll() {
20598
+ if (autoScrollId) {
20599
+ window.cancelAnimationFrame(autoScrollId);
20600
+ autoScrollId = 0;
20601
+ }
20602
+ stepX = 0;
20603
+ stepY = 0;
20604
+ };
20605
+ /** 从事件目标解析出「行 + 格 + 列序号 + 行偏移」 */
20606
+ var resolveCell = function resolveCell(parts, target) {
20607
+ var start = target;
20608
+ if (!start || !start.parentElement) return null;
20609
+ var row = start;
20610
+ while (row && row.parentElement !== parts.inner) {
20611
+ if (row === parts.holder || row === parts.inner) return null;
20612
+ row = row.parentElement;
20613
+ }
20614
+ if (!row) return null;
20615
+ var cell = start;
20616
+ while (cell && cell.parentElement !== row) cell = cell.parentElement;
20617
+ if (!cell) return null;
20618
+ var col = Array.from(row.children).indexOf(cell);
20619
+ if (col < 0) return null;
20620
+ var offset = Math.round(row.getBoundingClientRect().top - parts.inner.getBoundingClientRect().top);
20621
+ return {
20622
+ row: row,
20623
+ cell: cell,
20624
+ col: col,
20625
+ offset: offset
20626
+ };
20627
+ };
20628
+ var updateColumnEdges = function updateColumnEdges(sel, cells) {
20629
+ var leftCell = cells[Math.min(sel.startCol, sel.endCol)];
20630
+ var rightCell = cells[Math.max(sel.startCol, sel.endCol)];
20631
+ if (!leftCell || !rightCell) return;
20632
+ var holderRect = sel.holder.getBoundingClientRect();
20633
+ var contentLeft = holderRect.left + sel.holder.clientLeft - sel.holder.scrollLeft;
20634
+ sel.xLeft = leftCell.getBoundingClientRect().left - contentLeft;
20635
+ sel.xRight = rightCell.getBoundingClientRect().right - contentLeft;
20636
+ };
20637
+ /** 把当前渲染出来的、落在选区区间内的行收进 harvest */
20638
+ var harvest = function harvest() {
20639
+ var sel = selection;
20640
+ if (!sel) return;
20641
+ var from = Math.min(sel.startOffset, sel.endOffset);
20642
+ var to = Math.max(sel.startOffset, sel.endOffset);
20643
+ var rows = collectRenderedRows(sel.inner);
20644
+ rows.forEach(function (item) {
20645
+ if (item.offset < from || item.offset > to) return;
20646
+ sel.harvest.set(item.offset, item.cells.map(function (cell) {
20647
+ return cell.textContent || '';
20648
+ }));
20649
+ });
20650
+ if (rows.length) sel.rowHeight = estimateRowHeight(rows) || sel.rowHeight;
20651
+ var probe = rows.find(function (item) {
20652
+ return item.offset >= from && item.offset <= to;
20653
+ }) || rows[0];
20654
+ if (probe) updateColumnEdges(sel, probe.cells);
20655
+ };
20656
+ var paint = function paint() {
20657
+ rafId = 0;
20658
+ var sel = selection;
20659
+ if (!sel || !sel.holder.isConnected) {
20660
+ if (sel) clearSelection();
20661
+ return;
20662
+ }
20663
+ if (overlay.parentElement !== sel.holder) sel.holder.appendChild(overlay);
20664
+ var top = Math.min(sel.startOffset, sel.endOffset);
20665
+ var bottom = Math.max(sel.startOffset, sel.endOffset) + sel.rowHeight;
20666
+ overlay.style.display = 'block';
20667
+ overlay.style.left = sel.xLeft + 'px';
20668
+ overlay.style.top = top + 'px';
20669
+ overlay.style.width = Math.max(0, sel.xRight - sel.xLeft) + 'px';
20670
+ overlay.style.height = Math.max(0, bottom - top) + 'px';
20671
+ };
20672
+ var schedulePaint = function schedulePaint() {
20673
+ if (!rafId) rafId = window.requestAnimationFrame(paint);
20674
+ };
20675
+ var copySelection = function copySelection() {
20676
+ var sel = selection;
20677
+ if (!sel) return;
20678
+ harvest();
20679
+ var result = buildVirtualCopy(sel.harvest, sel.startOffset, sel.endOffset, sel.startCol, sel.endCol, sel.excludeCols, sel.rowHeight);
20680
+ if (!result.rowCount || !result.colCount) {
20681
+ message$1.warning('所选区域没有可复制的内容');
20682
+ return;
20683
+ }
20684
+ var tip = result.missingRows ? "\u5DF2\u590D\u5236 ".concat(result.rowCount, " \u884C \xD7 ").concat(result.colCount, " \u5217\uFF08\u53E6\u6709 ").concat(result.missingRows, " \u884C\u672A\u88AB\u6E32\u67D3\uFF0C\u672A\u5305\u542B\uFF09") : "\u5DF2\u590D\u5236 ".concat(result.rowCount, " \u884C \xD7 ").concat(result.colCount, " \u5217");
20685
+ writeClipboard(result.text).then(function (ok) {
20686
+ if (ok) message$1.success(tip);else message$1.error('复制失败,请按 Ctrl+C 重试');
20687
+ });
20688
+ };
20689
+ var applyPointerCell = function applyPointerCell() {
20690
+ var sel = selection;
20691
+ if (!sel) return;
20692
+ var holderRect = sel.holder.getBoundingClientRect();
20693
+ var x = Math.min(Math.max(pointerX, holderRect.left + 1), holderRect.right - 1);
20694
+ var y = Math.min(Math.max(pointerY, holderRect.top + 1), holderRect.bottom - 1);
20695
+ var hit = resolveCell(sel, document.elementFromPoint(x, y));
20696
+ if (!hit || hit.offset === sel.endOffset && hit.col === sel.endCol) return;
20697
+ sel.endOffset = hit.offset;
20698
+ sel.endCol = hit.col;
20699
+ harvest();
20700
+ schedulePaint();
20701
+ };
20702
+ var scrollerHasRoom = function scrollerHasRoom(el, dy, dx) {
20703
+ if (dy > 0) return el.scrollTop + el.clientHeight < el.scrollHeight - 1;
20704
+ if (dy < 0) return el.scrollTop > 0;
20705
+ if (dx > 0) return el.scrollLeft + el.clientWidth < el.scrollWidth - 1;
20706
+ if (dx < 0) return el.scrollLeft > 0;
20707
+ return false;
20708
+ };
20709
+ var edgeStep = function edgeStep(pos, min, max) {
20710
+ if (pos < min + EDGE_BAND$1) {
20711
+ return -Math.ceil(Math.min(1, (min + EDGE_BAND$1 - pos) / EDGE_BAND$1) * MAX_SCROLL_STEP$1);
20712
+ }
20713
+ if (pos > max - EDGE_BAND$1) {
20714
+ return Math.ceil(Math.min(1, (pos - (max - EDGE_BAND$1)) / EDGE_BAND$1) * MAX_SCROLL_STEP$1);
20715
+ }
20716
+ return 0;
20717
+ };
20718
+ var _autoScrollFrame = function autoScrollFrame() {
20719
+ autoScrollId = 0;
20720
+ var sel = selection;
20721
+ if (!sel || !stepX && !stepY) return;
20722
+ if (stepY) {
20723
+ if (scrollerHasRoom(sel.holder, stepY, 0)) sel.holder.scrollTop += stepY;else window.scrollBy(0, stepY);
20724
+ }
20725
+ if (stepX) {
20726
+ if (scrollerHasRoom(sel.holder, 0, stepX)) sel.holder.scrollLeft += stepX;else window.scrollBy(stepX, 0);
20727
+ }
20728
+ applyPointerCell();
20729
+ harvest();
20730
+ schedulePaint();
20731
+ autoScrollId = window.requestAnimationFrame(_autoScrollFrame);
20732
+ };
20733
+ var updateAutoScroll = function updateAutoScroll() {
20734
+ var sel = selection;
20735
+ if (!sel) {
20736
+ stopAutoScroll();
20737
+ return;
20738
+ }
20739
+ var rect = sel.holder.getBoundingClientRect();
20740
+ stepY = edgeStep(pointerY, rect.top, rect.bottom);
20741
+ stepX = edgeStep(pointerX, rect.left, rect.right);
20742
+ if (!stepX && !stepY) {
20743
+ stopAutoScroll();
20744
+ return;
20745
+ }
20746
+ if (!autoScrollId) autoScrollId = window.requestAnimationFrame(_autoScrollFrame);
20747
+ };
20748
+ var handleMouseDown = function handleMouseDown(e) {
20749
+ var _target$closest, _optionsRef$current2;
20750
+ if (e.button !== 0) return;
20751
+ suppressClick = false;
20752
+ var target = e.target;
20753
+ if ((_target$closest = target.closest) === null || _target$closest === void 0 ? void 0 : _target$closest.call(target, IGNORE_TARGET_SELECTOR$1)) return;
20754
+ if (!isVirtualBody(container)) return;
20755
+ var parts = getVirtualParts(container);
20756
+ if (!parts) return;
20757
+ var hit = resolveCell(parts, e.target);
20758
+ if (!hit) return;
20759
+ pointerX = e.clientX;
20760
+ pointerY = e.clientY;
20761
+ var excludeCols = resolveExcludeCols(parts.inner, ((_optionsRef$current2 = optionsRef.current) === null || _optionsRef$current2 === void 0 ? void 0 : _optionsRef$current2.excludeTitles) || DEFAULT_EXCLUDE_TITLES$1);
20762
+ var nextAnchor = {
20763
+ inner: parts.inner,
20764
+ holder: parts.holder,
20765
+ offset: hit.offset,
20766
+ col: hit.col,
20767
+ excludeCols: excludeCols
20768
+ };
20769
+ // Shift+点击:以既有基准行为另一头直接成矩形
20770
+ if (e.shiftKey && anchor && anchor.holder === parts.holder) {
20771
+ var _optionsRef$current$a, _optionsRef$current3;
20772
+ pressed = false;
20773
+ dragging = true;
20774
+ suppressClick = true;
20775
+ selection = {
20776
+ inner: parts.inner,
20777
+ holder: parts.holder,
20778
+ startOffset: anchor.offset,
20779
+ startCol: anchor.col,
20780
+ endOffset: hit.offset,
20781
+ endCol: hit.col,
20782
+ excludeCols: excludeCols,
20783
+ harvest: new Map(),
20784
+ xLeft: 0,
20785
+ xRight: 0,
20786
+ rowHeight: 0
20787
+ };
20788
+ harvest();
20789
+ schedulePaint();
20790
+ if ((_optionsRef$current$a = (_optionsRef$current3 = optionsRef.current) === null || _optionsRef$current3 === void 0 ? void 0 : _optionsRef$current3.autoCopy) !== null && _optionsRef$current$a !== void 0 ? _optionsRef$current$a : true) copySelection();
20791
+ return;
20792
+ }
20793
+ pressed = true;
20794
+ anchor = nextAnchor;
20795
+ };
20796
+ var handleMouseMove = function handleMouseMove(e) {
20797
+ if (!pressed) return;
20798
+ pointerX = e.clientX;
20799
+ pointerY = e.clientY;
20800
+ var base = anchor;
20801
+ if (!base) return;
20802
+ if (!dragging) {
20803
+ var hit = resolveCell(base, e.target);
20804
+ if (!hit) return;
20805
+ if (hit.offset === base.offset && hit.col === base.col) return;
20806
+ dragging = true;
20807
+ selection = {
20808
+ inner: base.inner,
20809
+ holder: base.holder,
20810
+ startOffset: base.offset,
20811
+ startCol: base.col,
20812
+ endOffset: hit.offset,
20813
+ endCol: hit.col,
20814
+ excludeCols: base.excludeCols,
20815
+ harvest: new Map(),
20816
+ xLeft: 0,
20817
+ xRight: 0,
20818
+ rowHeight: 0
20819
+ };
20820
+ harvest();
20821
+ } else {
20822
+ var sel = selection;
20823
+ if (!sel) return;
20824
+ var _hit = resolveCell(sel, e.target);
20825
+ if (!_hit) return;
20826
+ if (_hit.offset === sel.endOffset && _hit.col === sel.endCol) return;
20827
+ sel.endOffset = _hit.offset;
20828
+ sel.endCol = _hit.col;
20829
+ harvest();
20830
+ }
20831
+ schedulePaint();
20832
+ updateAutoScroll();
20833
+ };
20834
+ var handleMouseUp = function handleMouseUp() {
20835
+ var _optionsRef$current$a2, _optionsRef$current4;
20836
+ pressed = false;
20837
+ if (!dragging) return;
20838
+ dragging = false;
20839
+ stopAutoScroll();
20840
+ suppressClick = true;
20841
+ if ((_optionsRef$current$a2 = (_optionsRef$current4 = optionsRef.current) === null || _optionsRef$current4 === void 0 ? void 0 : _optionsRef$current4.autoCopy) !== null && _optionsRef$current$a2 !== void 0 ? _optionsRef$current$a2 : true) copySelection();
20842
+ schedulePaint();
20843
+ };
20844
+ var handleClickCapture = function handleClickCapture(e) {
20845
+ if (suppressClick) {
20846
+ suppressClick = false;
20847
+ e.stopPropagation();
20848
+ e.preventDefault();
20849
+ return;
20850
+ }
20851
+ var sel = selection;
20852
+ if (sel && !resolveCell(sel, e.target)) clearSelection();
20853
+ };
20854
+ var handleCopy = function handleCopy(e) {
20855
+ var _target$closest2;
20856
+ var sel = selection;
20857
+ if (!sel || !e.clipboardData) return;
20858
+ var target = e.target;
20859
+ if (target === null || target === void 0 ? void 0 : (_target$closest2 = target.closest) === null || _target$closest2 === void 0 ? void 0 : _target$closest2.call(target, 'input, textarea, [contenteditable="true"]')) return;
20860
+ harvest();
20861
+ var result = buildVirtualCopy(sel.harvest, sel.startOffset, sel.endOffset, sel.startCol, sel.endCol, sel.excludeCols, sel.rowHeight);
20862
+ if (!result.rowCount || !result.colCount) return;
20863
+ e.clipboardData.setData('text/plain', result.text);
20864
+ e.preventDefault();
20865
+ message$1.success("\u5DF2\u590D\u5236 ".concat(result.rowCount, " \u884C \xD7 ").concat(result.colCount, " \u5217"));
20866
+ };
20867
+ var handleKeyDown = function handleKeyDown(e) {
20868
+ if (e.key === 'Escape') clearSelection();
20869
+ };
20870
+ var handleBlur = function handleBlur() {
20871
+ pressed = false;
20872
+ dragging = false;
20873
+ suppressClick = false;
20874
+ stopAutoScroll();
20875
+ };
20876
+ container.addEventListener('mousedown', handleMouseDown);
20877
+ container.addEventListener('mousemove', handleMouseMove);
20878
+ container.addEventListener('click', handleClickCapture, true);
20879
+ document.addEventListener('mouseup', handleMouseUp);
20880
+ document.addEventListener('copy', handleCopy);
20881
+ document.addEventListener('keydown', handleKeyDown);
20882
+ window.addEventListener('blur', handleBlur);
20883
+ return function () {
20884
+ if (rafId) window.cancelAnimationFrame(rafId);
20885
+ stopAutoScroll();
20886
+ container.removeEventListener('mousedown', handleMouseDown);
20887
+ container.removeEventListener('mousemove', handleMouseMove);
20888
+ container.removeEventListener('click', handleClickCapture, true);
20889
+ document.removeEventListener('mouseup', handleMouseUp);
20890
+ document.removeEventListener('copy', handleCopy);
20891
+ document.removeEventListener('keydown', handleKeyDown);
20892
+ window.removeEventListener('blur', handleBlur);
20893
+ overlay.remove();
20894
+ };
20895
+ }, [enabled]);
20896
+ };
20897
+
20468
20898
  var _excluded$i = ["onResize", "width"];
20469
20899
  var MemoQueryTable = /*#__PURE__*/React$1.memo(QueryTable);
20470
20900
  var Text$2 = Typography.Text;
@@ -20594,12 +21024,19 @@ var BsSulaQueryTable = (function (props) {
20594
21024
  // 默认开启;rangeCopy={false} 可关;虚拟滚动表只渲染可视行、取不到整段选区,自动关闭
20595
21025
  var rangeCopyOption = props === null || props === void 0 ? void 0 : props.rangeCopy;
20596
21026
  var rangeCopyEnabled = rangeCopyOption !== false && !(props === null || props === void 0 ? void 0 : (_props$tableProps = props.tableProps) === null || _props$tableProps === void 0 ? void 0 : _props$tableProps.isVirtualTable);
20597
- var rangeCopyRef = useRangeCopy({
21027
+ // 只透传文档化的两个选项;不从对象里取 enabled,避免绕过上面的开关
21028
+ var rangeCopyOptions = {
20598
21029
  enabled: rangeCopyEnabled,
20599
- // 只透传文档化的两个选项;不从对象里取 enabled,避免绕过上面的开关
20600
21030
  excludeTitles: rangeCopyOption && _typeof(rangeCopyOption) === 'object' ? rangeCopyOption.excludeTitles : undefined,
20601
21031
  autoCopy: rangeCopyOption && _typeof(rangeCopyOption) === 'object' ? rangeCopyOption.autoCopy : undefined
20602
- });
21032
+ };
21033
+ // 常规表体(tr/td):经典路径
21034
+ var rangeCopyRef = useRangeCopy(rangeCopyOptions);
21035
+ // 虚拟滚动表(rc-virtual-list 表体,页面 tableProps.virtual):独立钩子,边滚边采已渲染行;
21036
+ // 经典钩子在虚拟表上找不到 tbody 会自动 no-op,两条路径互不干扰
21037
+ useVirtualRangeCopy(_objectSpread2(_objectSpread2({}, rangeCopyOptions), {}, {
21038
+ containerRef: rangeCopyRef
21039
+ }));
20603
21040
  // 获取 table columns中所有的 key 防止有的地方是 dataindex
20604
21041
  var checkedList = useMemo(function () {
20605
21042
  return props.columns.filter(function (col) {