@revolist/revogrid 4.23.7 → 4.23.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/cjs/{cell-renderer-Dcz022q7.js → cell-renderer-Dl9kKeKp.js} +1 -1
  2. package/dist/cjs/{column.drag.plugin-yUSx3qoN.js → column.drag.plugin-BRraLvz3.js} +34 -5
  3. package/dist/cjs/{column.service-C1Qvcf5l.js → column.service-BNWNiJW3.js} +62 -23
  4. package/dist/cjs/{header-cell-renderer-vVr4IWNV.js → header-cell-renderer-DyjOxArm.js} +1 -1
  5. package/dist/cjs/index.cjs.js +5 -4
  6. package/dist/cjs/revo-grid.cjs.entry.js +5 -5
  7. package/dist/cjs/revogr-attribution_7.cjs.entry.js +40 -4
  8. package/dist/cjs/revogr-data_4.cjs.entry.js +3 -3
  9. package/dist/cjs/revogr-filter-panel.cjs.entry.js +2 -2
  10. package/dist/collection/components/data/column.service.js +62 -23
  11. package/dist/collection/components/overlay/clipboard.utils.js +26 -0
  12. package/dist/collection/components/overlay/revogr-overlay-selection.js +27 -7
  13. package/dist/collection/components/revoGrid/revo-grid.js +14 -7
  14. package/dist/collection/plugins/filter/filter.panel.js +2 -2
  15. package/dist/collection/plugins/filter/filter.plugin.js +1 -1
  16. package/dist/collection/plugins/moveColumn/column.drag.plugin.js +30 -2
  17. package/dist/collection/serve/controller.js +1 -0
  18. package/dist/esm/{cell-renderer-BtN-NGCk.js → cell-renderer-CdF2Jm3B.js} +1 -1
  19. package/dist/esm/{column.drag.plugin-Cg2U-91C.js → column.drag.plugin-V9DDE3mU.js} +34 -6
  20. package/dist/esm/{column.service-CC_SD8W3.js → column.service-C6hByxPy.js} +62 -23
  21. package/dist/esm/{header-cell-renderer-B-LX2sgu.js → header-cell-renderer-BMmXRsd_.js} +1 -1
  22. package/dist/esm/index.js +5 -5
  23. package/dist/esm/revo-grid.entry.js +5 -5
  24. package/dist/esm/revogr-attribution_7.entry.js +40 -4
  25. package/dist/esm/revogr-data_4.entry.js +3 -3
  26. package/dist/esm/revogr-filter-panel.entry.js +2 -2
  27. package/dist/revo-grid/{cell-renderer-BtN-NGCk.js → cell-renderer-CdF2Jm3B.js} +1 -1
  28. package/dist/revo-grid/{column.drag.plugin-Cg2U-91C.js → column.drag.plugin-V9DDE3mU.js} +34 -6
  29. package/dist/revo-grid/{column.service-CC_SD8W3.js → column.service-C6hByxPy.js} +62 -23
  30. package/dist/revo-grid/{header-cell-renderer-B-LX2sgu.js → header-cell-renderer-BMmXRsd_.js} +1 -1
  31. package/dist/revo-grid/index.esm.js +5 -5
  32. package/dist/revo-grid/revo-grid.entry.js +5 -5
  33. package/dist/revo-grid/revogr-attribution_7.entry.js +40 -4
  34. package/dist/revo-grid/revogr-data_4.entry.js +3 -3
  35. package/dist/revo-grid/revogr-filter-panel.entry.js +2 -2
  36. package/dist/types/components/data/column.service.d.ts +10 -1
  37. package/dist/types/components/overlay/clipboard.utils.d.ts +3 -0
  38. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +4 -3
  39. package/dist/types/components/revoGrid/revo-grid.d.ts +4 -4
  40. package/dist/types/components.d.ts +14 -14
  41. package/dist/types/plugins/filter/filter.plugin.d.ts +1 -0
  42. package/dist/types/plugins/filter/filter.types.d.ts +1 -0
  43. package/dist/types/plugins/moveColumn/column.drag.plugin.d.ts +4 -0
  44. package/dist/types/types/interfaces.d.ts +8 -0
  45. package/hydrate/index.js +136 -33
  46. package/hydrate/index.mjs +136 -33
  47. package/package.json +1 -1
  48. package/readme.md +20 -1
  49. package/standalone/column.service.js +1 -1
  50. package/standalone/index.js +1 -1
  51. package/standalone/revo-grid.js +1 -1
  52. package/standalone/revogr-filter-panel.js +1 -1
  53. package/standalone/revogr-overlay-selection2.js +1 -1
@@ -5,7 +5,7 @@
5
5
 
6
6
  var index = require('./index-Dq8Xzj5l.js');
7
7
  var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
8
- var column_service = require('./column.service-C1Qvcf5l.js');
8
+ var column_service = require('./column.service-BNWNiJW3.js');
9
9
 
10
10
  /**
11
11
  * Renders sorting direction and optional additive sorting rank.
@@ -3,14 +3,14 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var column_service = require('./column.service-C1Qvcf5l.js');
6
+ var column_service = require('./column.service-BNWNiJW3.js');
7
7
  var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
8
8
  var viewport_store = require('./viewport.store-BscUCiUk.js');
9
9
  var index$1 = require('./index-DxaSE5uZ.js');
10
10
  var index = require('./index-Dq8Xzj5l.js');
11
11
  var filter_button = require('./filter.button-w6LWnyhi.js');
12
12
  var debounce = require('./debounce-CcpHiH2p.js');
13
- var headerCellRenderer = require('./header-cell-renderer-vVr4IWNV.js');
13
+ var headerCellRenderer = require('./header-cell-renderer-DyjOxArm.js');
14
14
 
15
15
  function calculateRealSize({ count, originItemSize, sizes, }) {
16
16
  const safeCount = Math.max(0, count);
@@ -1418,7 +1418,7 @@ class FilterPlugin extends BasePlugin {
1418
1418
  // filter button clicked, open filter dialog
1419
1419
  const gridPos = this.revogrid.getBoundingClientRect();
1420
1420
  const buttonPos = el.getBoundingClientRect();
1421
- const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent });
1421
+ const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x - gridPos.x, y: buttonPos.y - gridPos.y + buttonPos.height, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
1422
1422
  (_b = this.beforeshow) === null || _b === void 0 ? void 0 : _b.call(this, data);
1423
1423
  this.pop.show(data);
1424
1424
  }
@@ -2672,8 +2672,17 @@ class ColumnMovePlugin extends BasePlugin {
2672
2672
  constructor(revogrid, providers) {
2673
2673
  super(revogrid, providers);
2674
2674
  this.moveFunc = debounce.debounce((e) => this.doMove(e), 5);
2675
+ this.preventHeaderClickAfterDrag = (event) => {
2676
+ if (!this.preventNextHeaderClick) {
2677
+ return;
2678
+ }
2679
+ this.preventNextHeaderClick = false;
2680
+ event.preventDefault();
2681
+ };
2675
2682
  this.staticDragData = null;
2676
2683
  this.dragData = null;
2684
+ this.columnDragMoved = false;
2685
+ this.preventNextHeaderClick = false;
2677
2686
  this.localSubscriptions = {};
2678
2687
  this.orderUi = new ColumnOrderHandler();
2679
2688
  revogrid.appendChild(this.orderUi.render());
@@ -2692,11 +2701,13 @@ class ColumnMovePlugin extends BasePlugin {
2692
2701
  callback: (e) => this.move(e),
2693
2702
  };
2694
2703
  this.addEventListener(COLUMN_CLICK, ({ detail }) => this.dragStart(detail));
2704
+ this.revogrid.addEventListener('beforeheaderclick', this.preventHeaderClickAfterDrag, { capture: true });
2695
2705
  }
2696
2706
  dragStart({ event, data }) {
2697
2707
  if (event.defaultPrevented) {
2698
2708
  return;
2699
2709
  }
2710
+ this.preventNextHeaderClick = false;
2700
2711
  const { defaultPrevented } = headerCellRenderer.dispatch(this.revogrid, COLUMN_DRAG_START_EVENT, data);
2701
2712
  // check if allowed to drag particulat column
2702
2713
  if (defaultPrevented) {
@@ -2718,7 +2729,8 @@ class ColumnMovePlugin extends BasePlugin {
2718
2729
  const cols = this.getDimension(data.pin || 'rgCol');
2719
2730
  const gridRect = this.revogrid.getBoundingClientRect();
2720
2731
  const elRect = dataEl.getBoundingClientRect();
2721
- const startItem = dimension_helpers.getItemByPosition(cols, getLeftRelative(event.x, gridRect.left, elRect.left - gridRect.left) + (cols.renderOffset || 0));
2732
+ const startItem = dimension_helpers.getItemByPosition(cols, getLeftRelative(event.x, gridRect.left, elRect.left - gridRect.left) +
2733
+ (cols.renderOffset || 0));
2722
2734
  this.staticDragData = {
2723
2735
  startPos: event.x,
2724
2736
  startItem,
@@ -2749,10 +2761,14 @@ class ColumnMovePlugin extends BasePlugin {
2749
2761
  if (rgCol.itemIndex >= this.staticDragData.cols.count) {
2750
2762
  return;
2751
2763
  }
2752
- this.orderUi.showHandler(rgCol.end - (this.staticDragData.cols.renderOffset || 0) + dragData.scrollOffset, dragData.gridRect.width);
2764
+ this.orderUi.showHandler(getColumnDragPosition(rgCol, this.staticDragData.startItem, this.staticDragData.cols.renderOffset || 0, dragData.scrollOffset), dragData.gridRect.width);
2753
2765
  }
2754
2766
  }
2755
2767
  move(e) {
2768
+ if (this.staticDragData &&
2769
+ Math.abs(this.staticDragData.startPos - e.x) > 10) {
2770
+ this.columnDragMoved = true;
2771
+ }
2756
2772
  headerCellRenderer.dispatch(this.revogrid, COLUMN_DRAG_MOVE_EVENT, e);
2757
2773
  // then do move
2758
2774
  this.moveFunc(e);
@@ -2761,6 +2777,7 @@ class ColumnMovePlugin extends BasePlugin {
2761
2777
  this.clearOrder();
2762
2778
  }
2763
2779
  onMouseUp(e) {
2780
+ const suppressClick = this.columnDragMoved;
2764
2781
  // apply new positions
2765
2782
  if (this.dragData && this.staticDragData) {
2766
2783
  let relativePos = getLeftRelative(e.x, this.dragData.gridRect.left, this.dragData.scrollOffset);
@@ -2783,6 +2800,9 @@ class ColumnMovePlugin extends BasePlugin {
2783
2800
  }
2784
2801
  headerCellRenderer.dispatch(this.revogrid, COLUMN_DRAG_END_EVENT, this.getData(this.staticDragData, newItems, source));
2785
2802
  }
2803
+ if (suppressClick) {
2804
+ this.preventNextHeaderClick = !!e.target.closest('revogr-header');
2805
+ }
2786
2806
  this.clearOrder();
2787
2807
  }
2788
2808
  clearLocalSubscriptions() {
@@ -2791,6 +2811,7 @@ class ColumnMovePlugin extends BasePlugin {
2791
2811
  clearOrder() {
2792
2812
  this.staticDragData = null;
2793
2813
  this.dragData = null;
2814
+ this.columnDragMoved = false;
2794
2815
  this.clearLocalSubscriptions();
2795
2816
  this.orderUi.stop(this.revogrid);
2796
2817
  }
@@ -2800,6 +2821,7 @@ class ColumnMovePlugin extends BasePlugin {
2800
2821
  clearSubscriptions() {
2801
2822
  super.clearSubscriptions();
2802
2823
  this.clearLocalSubscriptions();
2824
+ this.revogrid.removeEventListener('beforeheaderclick', this.preventHeaderClickAfterDrag, { capture: true });
2803
2825
  }
2804
2826
  getData({ gridEl, dataEl, pin }, order, source = []) {
2805
2827
  const gridRect = gridEl.getBoundingClientRect();
@@ -2821,6 +2843,12 @@ class ColumnMovePlugin extends BasePlugin {
2821
2843
  function getLeftRelative(absoluteX, gridPos, offset) {
2822
2844
  return absoluteX - gridPos - offset;
2823
2845
  }
2846
+ function getColumnDragPosition(targetItem, startItem, renderOffset, scrollOffset) {
2847
+ const insertionEdge = startItem.itemIndex > targetItem.itemIndex
2848
+ ? targetItem.start
2849
+ : targetItem.end;
2850
+ return insertionEdge - renderOffset + scrollOffset;
2851
+ }
2824
2852
 
2825
2853
  exports.AutoSizeColumnPlugin = AutoSizeColumnPlugin;
2826
2854
  exports.BEFORE_COLUMN_DRAG_END_EVENT = BEFORE_COLUMN_DRAG_END_EVENT;
@@ -2847,6 +2875,7 @@ exports.doExpand = doExpand;
2847
2875
  exports.filterCoreFunctionsIndexedByType = filterCoreFunctionsIndexedByType;
2848
2876
  exports.filterNames = filterNames;
2849
2877
  exports.filterTypes = filterTypes;
2878
+ exports.getColumnDragPosition = getColumnDragPosition;
2850
2879
  exports.getComparer = getComparer;
2851
2880
  exports.getLeftRelative = getLeftRelative;
2852
2881
  exports.getNextOrder = getNextOrder;
@@ -819,43 +819,82 @@ class ColumnService {
819
819
  mapping,
820
820
  };
821
821
  }
822
- getTransformedDataToApply(start, data) {
822
+ getTransformedDataToApply({ start, data, targetRange, }) {
823
823
  const changed = {};
824
824
  const copyRowLength = data.length;
825
+ if (!copyRowLength) {
826
+ return {
827
+ changed,
828
+ range: null,
829
+ };
830
+ }
825
831
  const colLength = this.columns.length;
826
832
  const rowLength = this.dataStore.get('items').length;
833
+ const bounds = this.getDataApplyBounds(start, targetRange, copyRowLength, rowLength, colLength);
834
+ if (!bounds) {
835
+ return {
836
+ changed,
837
+ range: null,
838
+ };
839
+ }
840
+ const { startRow, startCol, endRow } = bounds;
841
+ let maxCol = startCol - 1;
842
+ let lastRow = startRow - 1;
827
843
  // rows
828
- let rowIndex = start.y;
829
- let maxCol = 0;
830
- for (let i = 0; rowIndex < rowLength && i < copyRowLength; rowIndex++, i++) {
844
+ for (let rowIndex = startRow, i = 0; rowIndex <= endRow; rowIndex++, i++) {
831
845
  // copy original data link
832
846
  const copyRow = data[i % copyRowLength];
833
847
  const copyColLength = (copyRow === null || copyRow === void 0 ? void 0 : copyRow.length) || 0;
834
- // columns
835
- let colIndex = start.x;
836
- for (let j = 0; colIndex < colLength && j < copyColLength; colIndex++, j++) {
837
- const p = this.columns[colIndex].prop;
838
- const currentCol = j % colLength;
839
- /** if can write */
840
- if (!this.isReadOnly(rowIndex, colIndex)) {
841
- /** to show before save */
842
- if (!changed[rowIndex]) {
843
- changed[rowIndex] = {};
844
- }
845
- changed[rowIndex][p] = copyRow[currentCol];
846
- }
848
+ if (!copyColLength) {
849
+ continue;
847
850
  }
848
- maxCol = Math.max(maxCol, colIndex - 1);
851
+ maxCol = Math.max(maxCol, this.applyClipboardRow(changed, {
852
+ bounds,
853
+ copyColLength,
854
+ copyRow,
855
+ rowIndex,
856
+ start,
857
+ targetRange,
858
+ }));
859
+ lastRow = rowIndex;
849
860
  }
850
- const range = getRange(start, {
851
- y: rowIndex - 1,
852
- x: maxCol,
853
- });
854
861
  return {
855
862
  changed,
856
- range,
863
+ range: this.getAppliedRange(bounds, lastRow, maxCol),
857
864
  };
858
865
  }
866
+ getDataApplyBounds(start, targetRange, copyRowLength, rowLength, colLength) {
867
+ var _a, _b, _c;
868
+ const startRow = (_a = targetRange === null || targetRange === void 0 ? void 0 : targetRange.y) !== null && _a !== void 0 ? _a : start.y;
869
+ const startCol = (_b = targetRange === null || targetRange === void 0 ? void 0 : targetRange.x) !== null && _b !== void 0 ? _b : start.x;
870
+ const endRow = Math.min(rowLength - 1, (_c = targetRange === null || targetRange === void 0 ? void 0 : targetRange.y1) !== null && _c !== void 0 ? _c : start.y + copyRowLength - 1);
871
+ if (endRow < startRow || startCol >= colLength) {
872
+ return null;
873
+ }
874
+ return { startRow, startCol, endRow, colLength };
875
+ }
876
+ applyClipboardRow(changed, { bounds, copyColLength, copyRow, rowIndex, start, targetRange, }) {
877
+ var _a;
878
+ const endCol = Math.min(bounds.colLength - 1, (_a = targetRange === null || targetRange === void 0 ? void 0 : targetRange.x1) !== null && _a !== void 0 ? _a : start.x + copyColLength - 1);
879
+ for (let colIndex = bounds.startCol, j = 0; colIndex <= endCol; colIndex++, j++) {
880
+ if (this.isReadOnly(rowIndex, colIndex)) {
881
+ continue;
882
+ }
883
+ const prop = this.columns[colIndex].prop;
884
+ changed[rowIndex] = changed[rowIndex] || {};
885
+ changed[rowIndex][prop] = copyRow[j % copyColLength];
886
+ }
887
+ return endCol;
888
+ }
889
+ getAppliedRange({ startRow, startCol }, lastRow, maxCol) {
890
+ if (lastRow < startRow || maxCol < startCol) {
891
+ return null;
892
+ }
893
+ return getRange({ x: startCol, y: startRow }, {
894
+ y: lastRow,
895
+ x: maxCol,
896
+ });
897
+ }
859
898
  getRangeStaticData(d, value) {
860
899
  const changed = {};
861
900
  // rows
@@ -4,7 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-Dq8Xzj5l.js');
7
- var column_service = require('./column.service-C1Qvcf5l.js');
7
+ var column_service = require('./column.service-BNWNiJW3.js');
8
8
 
9
9
  /**
10
10
  * Dispatches a custom event to a specified target element.
@@ -3,10 +3,10 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var column_service = require('./column.service-C1Qvcf5l.js');
7
- var column_drag_plugin = require('./column.drag.plugin-yUSx3qoN.js');
8
- var headerCellRenderer = require('./header-cell-renderer-vVr4IWNV.js');
9
- var cellRenderer = require('./cell-renderer-Dcz022q7.js');
6
+ var column_service = require('./column.service-BNWNiJW3.js');
7
+ var column_drag_plugin = require('./column.drag.plugin-BRraLvz3.js');
8
+ var headerCellRenderer = require('./header-cell-renderer-DyjOxArm.js');
9
+ var cellRenderer = require('./cell-renderer-Dl9kKeKp.js');
10
10
  var index$1 = require('./index-DxaSE5uZ.js');
11
11
  var textEditor = require('./text-editor-B4W-m-r-.js');
12
12
  var edit_utils = require('./edit.utils-pKeiYFLJ.js');
@@ -233,6 +233,7 @@ exports.doExpand = column_drag_plugin.doExpand;
233
233
  exports.filterCoreFunctionsIndexedByType = column_drag_plugin.filterCoreFunctionsIndexedByType;
234
234
  exports.filterNames = column_drag_plugin.filterNames;
235
235
  exports.filterTypes = column_drag_plugin.filterTypes;
236
+ exports.getColumnDragPosition = column_drag_plugin.getColumnDragPosition;
236
237
  exports.getComparer = column_drag_plugin.getComparer;
237
238
  exports.getLeftRelative = column_drag_plugin.getLeftRelative;
238
239
  exports.getNextOrder = column_drag_plugin.getNextOrder;
@@ -4,17 +4,17 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-Dq8Xzj5l.js');
7
- var column_service = require('./column.service-C1Qvcf5l.js');
7
+ var column_service = require('./column.service-BNWNiJW3.js');
8
8
  var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
9
9
  var debounce = require('./debounce-CcpHiH2p.js');
10
10
  var viewport_helpers = require('./viewport.helpers-BND76K2j.js');
11
- var column_drag_plugin = require('./column.drag.plugin-yUSx3qoN.js');
11
+ var column_drag_plugin = require('./column.drag.plugin-BRraLvz3.js');
12
12
  var viewport_store = require('./viewport.store-BscUCiUk.js');
13
13
  var theme_service = require('./theme.service-BgnxGIjK.js');
14
14
  var index$1 = require('./index-DxaSE5uZ.js');
15
15
  var events = require('./events-DeLDyZlb.js');
16
16
  require('./filter.button-w6LWnyhi.js');
17
- require('./header-cell-renderer-vVr4IWNV.js');
17
+ require('./header-cell-renderer-DyjOxArm.js');
18
18
 
19
19
  class ColumnDataProvider {
20
20
  get stores() {
@@ -1447,7 +1447,7 @@ const RevoGridComponent = class {
1447
1447
  this.rowSize = 0;
1448
1448
  /** Indicates default column size. */
1449
1449
  this.colSize = 100;
1450
- /** When true, user can range selection. */
1450
+ /** When true, user can select a cell range. Required for range-based clipboard fill. */
1451
1451
  this.range = false;
1452
1452
  /** When true, grid in read only mode. */
1453
1453
  this.readonly = false;
@@ -1459,7 +1459,7 @@ const RevoGridComponent = class {
1459
1459
  this.noHorizontalScrollTransfer = false;
1460
1460
  /** When true cell focus appear. */
1461
1461
  this.canFocus = true;
1462
- /** When true enable clipboard. */
1462
+ /** When true enable clipboard. Can be boolean or clipboard config. */
1463
1463
  this.useClipboard = true;
1464
1464
  /**
1465
1465
  * Columns - defines an array of grid columns.
@@ -6,7 +6,7 @@
6
6
  var index = require('./index-Dq8Xzj5l.js');
7
7
  var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
8
8
  var events = require('./events-DeLDyZlb.js');
9
- var column_service = require('./column.service-C1Qvcf5l.js');
9
+ var column_service = require('./column.service-BNWNiJW3.js');
10
10
  var edit_utils = require('./edit.utils-pKeiYFLJ.js');
11
11
  var index$1 = require('./index-DxaSE5uZ.js');
12
12
  var debounce = require('./debounce-CcpHiH2p.js');
@@ -651,6 +651,30 @@ class AutoFillService {
651
651
  }
652
652
  }
653
653
 
654
+ function getRangeFillClipboardData(data, useClipboard) {
655
+ var _a;
656
+ if (!isClipboardRangeFillEnabled(useClipboard)) {
657
+ return null;
658
+ }
659
+ const normalized = trimTrailingEmptyClipboardRows(data);
660
+ return normalized.length === 1 && ((_a = normalized[0]) === null || _a === void 0 ? void 0 : _a.length) === 1
661
+ ? normalized
662
+ : null;
663
+ }
664
+ function isClipboardRangeFillEnabled(useClipboard) {
665
+ return (typeof useClipboard === 'object' && useClipboard.rangeFill === true);
666
+ }
667
+ function trimTrailingEmptyClipboardRows(data) {
668
+ const rows = [...data];
669
+ while (rows.length > 1 && isEmptyClipboardRow(rows[rows.length - 1])) {
670
+ rows.pop();
671
+ }
672
+ return rows;
673
+ }
674
+ function isEmptyClipboardRow(row) {
675
+ return !row || row.every(cell => cell === '');
676
+ }
677
+
654
678
  const revogrOverlayStyleCss = () => `revogr-overlay-selection{display:block;position:relative;width:100%}revogr-overlay-selection .autofill-handle{position:absolute;width:14px;height:14px;margin-left:-13px;margin-top:-13px;z-index:10;cursor:crosshair}revogr-overlay-selection .autofill-handle::before{content:"";position:absolute;right:0;bottom:0;width:10px;height:10px;background:#0d63e8;border:1px solid white;box-sizing:border-box}revogr-overlay-selection.mobile .autofill-handle{position:absolute;width:30px;height:30px;margin-left:-29px;margin-top:-29px;z-index:10;cursor:crosshair}revogr-overlay-selection.mobile .autofill-handle::before{content:"";position:absolute;right:0;bottom:0;width:12px;height:12px;background:#0d63e8;border:1px solid white;box-sizing:border-box}revogr-overlay-selection .selection-border-range{position:absolute;pointer-events:none;z-index:9;box-shadow:-1px 0 0 #0d63e8 inset, 1px 0 0 #0d63e8 inset, 0 -1px 0 #0d63e8 inset, 0 1px 0 #0d63e8 inset}revogr-overlay-selection .selection-border-range .range-handlers{height:100%;background-color:transparent;width:75%;max-width:50px;min-width:20px;left:50%;transform:translateX(-50%);position:absolute}revogr-overlay-selection .selection-border-range .range-handlers>span{pointer-events:auto;height:20px;width:20px;position:absolute;left:50%;transform:translateX(-50%)}revogr-overlay-selection .selection-border-range .range-handlers>span:before,revogr-overlay-selection .selection-border-range .range-handlers>span:after{position:absolute;border-radius:5px;width:15px;height:5px;left:50%;transform:translateX(-50%);background-color:rgba(0, 0, 0, 0.2)}revogr-overlay-selection .selection-border-range .range-handlers>span:first-child{top:-7px}revogr-overlay-selection .selection-border-range .range-handlers>span:first-child:before{content:"";top:0}revogr-overlay-selection .selection-border-range .range-handlers>span:last-child{bottom:-7px}revogr-overlay-selection .selection-border-range .range-handlers>span:last-child:after{content:"";bottom:0}revogr-overlay-selection revogr-edit{z-index:10}`;
655
679
 
656
680
  const OverlaySelection = class {
@@ -898,9 +922,9 @@ const OverlaySelection = class {
898
922
  nodes.push(index.h("revogr-order-editor", { ref: e => (this.orderEditor = e), dataStore: this.dataStore, dimensionRow: this.dimensionRow, dimensionCol: this.dimensionCol, parent: this.element, rowType: this.types.rowType, onRowdragstartinit: e => this.rowDragStart(e) }));
899
923
  }
900
924
  }
901
- return (index.h(index.Host, { key: 'd936e8452e84c7a25ecd6502e929f1a5af69467f', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
925
+ return (index.h(index.Host, { key: 'ff303c39d59e4ef217421fa11b9a80de07311b07', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
902
926
  // it's done to be able to throw events from different levels, not just from editor
903
- onCelledit: (e) => this.onEditCell(e) }, nodes, index.h("slot", { key: 'cd3525d404aa44fd8d06e7fc459777acb8a9d585', name: "data" })));
927
+ onCelledit: (e) => this.onEditCell(e) }, nodes, index.h("slot", { key: '3cbe4c3ad7d447f779e9e20f73eec2e3107275e0', name: "data" })));
904
928
  }
905
929
  /**
906
930
  * Executes the focus operation on the specified range of cells.
@@ -1065,13 +1089,25 @@ const OverlaySelection = class {
1065
1089
  if (!focus || isEditing) {
1066
1090
  return;
1067
1091
  }
1068
- let { changed, range } = this.columnService.getTransformedDataToApply(focus, data);
1092
+ const rangeFillData = getRangeFillClipboardData(data, this.useClipboard);
1093
+ const targetRange = rangeFillData
1094
+ ? this.getClipboardPasteTargetRange()
1095
+ : null;
1096
+ let { changed, range } = this.columnService.getTransformedDataToApply({
1097
+ start: focus,
1098
+ data: rangeFillData || data,
1099
+ targetRange,
1100
+ });
1069
1101
  const { defaultPrevented: canPaste } = this.rangeClipboardPaste.emit(Object.assign({ data: changed, models: collectModelsOfRange(changed, this.dataStore), range }, this.types));
1070
1102
  if (canPaste) {
1071
1103
  return;
1072
1104
  }
1073
1105
  (_a = this.autoFillService) === null || _a === void 0 ? void 0 : _a.onRangeApply(changed, range, range);
1074
1106
  }
1107
+ getClipboardPasteTargetRange() {
1108
+ const range = this.selectionStore.get('range');
1109
+ return range && !column_service.isRangeSingleCell(range) ? range : null;
1110
+ }
1075
1111
  async focusNext() {
1076
1112
  var _a;
1077
1113
  const canFocus = await ((_a = this.keyboardService) === null || _a === void 0 ? void 0 : _a.keyChangeSelection(new KeyboardEvent('keydown', {
@@ -4,11 +4,11 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-Dq8Xzj5l.js');
7
- var column_service = require('./column.service-C1Qvcf5l.js');
7
+ var column_service = require('./column.service-BNWNiJW3.js');
8
8
  var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
9
- var cellRenderer = require('./cell-renderer-Dcz022q7.js');
9
+ var cellRenderer = require('./cell-renderer-Dl9kKeKp.js');
10
10
  var filter_button = require('./filter.button-w6LWnyhi.js');
11
- var headerCellRenderer = require('./header-cell-renderer-vVr4IWNV.js');
11
+ var headerCellRenderer = require('./header-cell-renderer-DyjOxArm.js');
12
12
  var throttle = require('./throttle-BCwEuJJq.js');
13
13
  var viewport_helpers = require('./viewport.helpers-BND76K2j.js');
14
14
  require('./debounce-CcpHiH2p.js');
@@ -348,7 +348,7 @@ const FilterPanel = class {
348
348
  } }));
349
349
  }
350
350
  render() {
351
- var _a, _b, _c;
351
+ var _a, _b, _c, _d, _e;
352
352
  if (!this.changes) {
353
353
  return index.h(index.Host, { style: { display: 'none' } });
354
354
  }
@@ -365,7 +365,7 @@ const FilterPanel = class {
365
365
  index.h("label", null, capts.title),
366
366
  index.h("div", { class: "filter-holder" }, this.getFilterItemsList()),
367
367
  index.h("div", { class: "add-filter" }, index.h("select", { id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType)))
368
- ]), index.h("slot", null), index.h("div", { class: "filter-actions" }, this.disableDynamicFiltering && [
368
+ ]), index.h("slot", null), ((_e = (_d = this.changes).extraBottomContent) === null || _e === void 0 ? void 0 : _e.call(_d, this.changes)) || '', index.h("div", { class: "filter-actions" }, this.disableDynamicFiltering && [
369
369
  index.h("button", { id: "revo-button-save", "aria-label": "save", class: "revo-button green", onClick: () => this.onSave() }, capts.save),
370
370
  index.h("button", { id: "revo-button-ok", "aria-label": "ok", class: "revo-button green", onClick: () => this.onCancel() }, capts.cancel),
371
371
  ], !this.disableDynamicFiltering && [
@@ -144,43 +144,82 @@ export default class ColumnService {
144
144
  mapping,
145
145
  };
146
146
  }
147
- getTransformedDataToApply(start, data) {
147
+ getTransformedDataToApply({ start, data, targetRange, }) {
148
148
  const changed = {};
149
149
  const copyRowLength = data.length;
150
+ if (!copyRowLength) {
151
+ return {
152
+ changed,
153
+ range: null,
154
+ };
155
+ }
150
156
  const colLength = this.columns.length;
151
157
  const rowLength = this.dataStore.get('items').length;
158
+ const bounds = this.getDataApplyBounds(start, targetRange, copyRowLength, rowLength, colLength);
159
+ if (!bounds) {
160
+ return {
161
+ changed,
162
+ range: null,
163
+ };
164
+ }
165
+ const { startRow, startCol, endRow } = bounds;
166
+ let maxCol = startCol - 1;
167
+ let lastRow = startRow - 1;
152
168
  // rows
153
- let rowIndex = start.y;
154
- let maxCol = 0;
155
- for (let i = 0; rowIndex < rowLength && i < copyRowLength; rowIndex++, i++) {
169
+ for (let rowIndex = startRow, i = 0; rowIndex <= endRow; rowIndex++, i++) {
156
170
  // copy original data link
157
171
  const copyRow = data[i % copyRowLength];
158
172
  const copyColLength = (copyRow === null || copyRow === void 0 ? void 0 : copyRow.length) || 0;
159
- // columns
160
- let colIndex = start.x;
161
- for (let j = 0; colIndex < colLength && j < copyColLength; colIndex++, j++) {
162
- const p = this.columns[colIndex].prop;
163
- const currentCol = j % colLength;
164
- /** if can write */
165
- if (!this.isReadOnly(rowIndex, colIndex)) {
166
- /** to show before save */
167
- if (!changed[rowIndex]) {
168
- changed[rowIndex] = {};
169
- }
170
- changed[rowIndex][p] = copyRow[currentCol];
171
- }
173
+ if (!copyColLength) {
174
+ continue;
172
175
  }
173
- maxCol = Math.max(maxCol, colIndex - 1);
176
+ maxCol = Math.max(maxCol, this.applyClipboardRow(changed, {
177
+ bounds,
178
+ copyColLength,
179
+ copyRow,
180
+ rowIndex,
181
+ start,
182
+ targetRange,
183
+ }));
184
+ lastRow = rowIndex;
174
185
  }
175
- const range = getRange(start, {
176
- y: rowIndex - 1,
177
- x: maxCol,
178
- });
179
186
  return {
180
187
  changed,
181
- range,
188
+ range: this.getAppliedRange(bounds, lastRow, maxCol),
182
189
  };
183
190
  }
191
+ getDataApplyBounds(start, targetRange, copyRowLength, rowLength, colLength) {
192
+ var _a, _b, _c;
193
+ const startRow = (_a = targetRange === null || targetRange === void 0 ? void 0 : targetRange.y) !== null && _a !== void 0 ? _a : start.y;
194
+ const startCol = (_b = targetRange === null || targetRange === void 0 ? void 0 : targetRange.x) !== null && _b !== void 0 ? _b : start.x;
195
+ const endRow = Math.min(rowLength - 1, (_c = targetRange === null || targetRange === void 0 ? void 0 : targetRange.y1) !== null && _c !== void 0 ? _c : start.y + copyRowLength - 1);
196
+ if (endRow < startRow || startCol >= colLength) {
197
+ return null;
198
+ }
199
+ return { startRow, startCol, endRow, colLength };
200
+ }
201
+ applyClipboardRow(changed, { bounds, copyColLength, copyRow, rowIndex, start, targetRange, }) {
202
+ var _a;
203
+ const endCol = Math.min(bounds.colLength - 1, (_a = targetRange === null || targetRange === void 0 ? void 0 : targetRange.x1) !== null && _a !== void 0 ? _a : start.x + copyColLength - 1);
204
+ for (let colIndex = bounds.startCol, j = 0; colIndex <= endCol; colIndex++, j++) {
205
+ if (this.isReadOnly(rowIndex, colIndex)) {
206
+ continue;
207
+ }
208
+ const prop = this.columns[colIndex].prop;
209
+ changed[rowIndex] = changed[rowIndex] || {};
210
+ changed[rowIndex][prop] = copyRow[j % copyColLength];
211
+ }
212
+ return endCol;
213
+ }
214
+ getAppliedRange({ startRow, startCol }, lastRow, maxCol) {
215
+ if (lastRow < startRow || maxCol < startCol) {
216
+ return null;
217
+ }
218
+ return getRange({ x: startCol, y: startRow }, {
219
+ y: lastRow,
220
+ x: maxCol,
221
+ });
222
+ }
184
223
  getRangeStaticData(d, value) {
185
224
  const changed = {};
186
225
  // rows
@@ -0,0 +1,26 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ export function getRangeFillClipboardData(data, useClipboard) {
5
+ var _a;
6
+ if (!isClipboardRangeFillEnabled(useClipboard)) {
7
+ return null;
8
+ }
9
+ const normalized = trimTrailingEmptyClipboardRows(data);
10
+ return normalized.length === 1 && ((_a = normalized[0]) === null || _a === void 0 ? void 0 : _a.length) === 1
11
+ ? normalized
12
+ : null;
13
+ }
14
+ export function isClipboardRangeFillEnabled(useClipboard) {
15
+ return (typeof useClipboard === 'object' && useClipboard.rangeFill === true);
16
+ }
17
+ function trimTrailingEmptyClipboardRows(data) {
18
+ const rows = [...data];
19
+ while (rows.length > 1 && isEmptyClipboardRow(rows[rows.length - 1])) {
20
+ rows.pop();
21
+ }
22
+ return rows;
23
+ }
24
+ function isEmptyClipboardRow(row) {
25
+ return !row || row.every(cell => cell === '');
26
+ }
@@ -10,6 +10,7 @@ import { collectModelsOfRange, getCell, getFocusCellBasedOnEvent, styleByCellPro
10
10
  import { isEditInput } from "../editors/edit.utils";
11
11
  import { KeyboardService } from "./keyboard.service";
12
12
  import { AutoFillService } from "./autofill.service";
13
+ import { getRangeFillClipboardData } from "./clipboard.utils";
13
14
  import { verifyTouchTarget } from "../../utils/events";
14
15
  import { getCellData } from "../../utils";
15
16
  /**
@@ -233,9 +234,9 @@ export class OverlaySelection {
233
234
  nodes.push(h("revogr-order-editor", { ref: e => (this.orderEditor = e), dataStore: this.dataStore, dimensionRow: this.dimensionRow, dimensionCol: this.dimensionCol, parent: this.element, rowType: this.types.rowType, onRowdragstartinit: e => this.rowDragStart(e) }));
234
235
  }
235
236
  }
236
- return (h(Host, { key: 'd936e8452e84c7a25ecd6502e929f1a5af69467f', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
237
+ return (h(Host, { key: 'ff303c39d59e4ef217421fa11b9a80de07311b07', class: { mobile: this.isMobileDevice }, onDblClick: (e) => this.onElementDblClick(e), onMouseDown: (e) => this.onElementMouseDown(e), onTouchStart: (e) => this.onElementMouseDown(e, true), onCloseedit: (e) => this.closeEdit(e),
237
238
  // it's done to be able to throw events from different levels, not just from editor
238
- onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: 'cd3525d404aa44fd8d06e7fc459777acb8a9d585', name: "data" })));
239
+ onCelledit: (e) => this.onEditCell(e) }, nodes, h("slot", { key: '3cbe4c3ad7d447f779e9e20f73eec2e3107275e0', name: "data" })));
239
240
  }
240
241
  /**
241
242
  * Executes the focus operation on the specified range of cells.
@@ -400,13 +401,25 @@ export class OverlaySelection {
400
401
  if (!focus || isEditing) {
401
402
  return;
402
403
  }
403
- let { changed, range } = this.columnService.getTransformedDataToApply(focus, data);
404
+ const rangeFillData = getRangeFillClipboardData(data, this.useClipboard);
405
+ const targetRange = rangeFillData
406
+ ? this.getClipboardPasteTargetRange()
407
+ : null;
408
+ let { changed, range } = this.columnService.getTransformedDataToApply({
409
+ start: focus,
410
+ data: rangeFillData || data,
411
+ targetRange,
412
+ });
404
413
  const { defaultPrevented: canPaste } = this.rangeClipboardPaste.emit(Object.assign({ data: changed, models: collectModelsOfRange(changed, this.dataStore), range }, this.types));
405
414
  if (canPaste) {
406
415
  return;
407
416
  }
408
417
  (_a = this.autoFillService) === null || _a === void 0 ? void 0 : _a.onRangeApply(changed, range, range);
409
418
  }
419
+ getClipboardPasteTargetRange() {
420
+ const range = this.selectionStore.get('range');
421
+ return range && !isRangeSingleCell(range) ? range : null;
422
+ }
410
423
  async focusNext() {
411
424
  var _a;
412
425
  const canFocus = await ((_a = this.keyboardService) === null || _a === void 0 ? void 0 : _a.keyChangeSelection(new KeyboardEvent('keydown', {
@@ -565,15 +578,22 @@ export class OverlaySelection {
565
578
  "type": "boolean",
566
579
  "mutable": false,
567
580
  "complexType": {
568
- "original": "boolean",
569
- "resolved": "boolean",
570
- "references": {}
581
+ "original": "boolean | ClipboardConfig",
582
+ "resolved": "ClipboardConfig | boolean",
583
+ "references": {
584
+ "ClipboardConfig": {
585
+ "location": "import",
586
+ "path": "@type",
587
+ "id": "src/types/index.ts::ClipboardConfig",
588
+ "referenceLocation": "ClipboardConfig"
589
+ }
590
+ }
571
591
  },
572
592
  "required": false,
573
593
  "optional": false,
574
594
  "docs": {
575
595
  "tags": [],
576
- "text": "Enable revogr-clipboard component (read more in revogr-clipboard component).\nAllows copy/paste."
596
+ "text": "Enable revogr-clipboard component (read more in revogr-clipboard component).\nAllows copy/paste. Can be boolean or clipboard config."
577
597
  },
578
598
  "getter": false,
579
599
  "setter": false,