@revolist/revogrid 4.23.8 → 4.23.10

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 (41) hide show
  1. package/dist/cjs/{cell-renderer-Dcz022q7.js → cell-renderer-Dl9kKeKp.js} +1 -1
  2. package/dist/cjs/{column.drag.plugin-CHyc9aCK.js → column.drag.plugin-BRraLvz3.js} +2 -2
  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 +4 -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/collection/components/data/column.service.js +62 -23
  10. package/dist/collection/components/overlay/clipboard.utils.js +26 -0
  11. package/dist/collection/components/overlay/revogr-overlay-selection.js +27 -7
  12. package/dist/collection/components/revoGrid/revo-grid.js +14 -7
  13. package/dist/collection/serve/controller.js +1 -0
  14. package/dist/esm/{cell-renderer-BtN-NGCk.js → cell-renderer-CdF2Jm3B.js} +1 -1
  15. package/dist/esm/{column.drag.plugin-DEKk4rrp.js → column.drag.plugin-V9DDE3mU.js} +2 -2
  16. package/dist/esm/{column.service-CC_SD8W3.js → column.service-C6hByxPy.js} +62 -23
  17. package/dist/esm/{header-cell-renderer-B-LX2sgu.js → header-cell-renderer-BMmXRsd_.js} +1 -1
  18. package/dist/esm/index.js +5 -5
  19. package/dist/esm/revo-grid.entry.js +5 -5
  20. package/dist/esm/revogr-attribution_7.entry.js +40 -4
  21. package/dist/esm/revogr-data_4.entry.js +3 -3
  22. package/dist/revo-grid/{cell-renderer-BtN-NGCk.js → cell-renderer-CdF2Jm3B.js} +1 -1
  23. package/dist/revo-grid/{column.drag.plugin-DEKk4rrp.js → column.drag.plugin-V9DDE3mU.js} +2 -2
  24. package/dist/revo-grid/{column.service-CC_SD8W3.js → column.service-C6hByxPy.js} +62 -23
  25. package/dist/revo-grid/{header-cell-renderer-B-LX2sgu.js → header-cell-renderer-BMmXRsd_.js} +1 -1
  26. package/dist/revo-grid/index.esm.js +5 -5
  27. package/dist/revo-grid/revo-grid.entry.js +5 -5
  28. package/dist/revo-grid/revogr-attribution_7.entry.js +40 -4
  29. package/dist/revo-grid/revogr-data_4.entry.js +3 -3
  30. package/dist/types/components/data/column.service.d.ts +10 -1
  31. package/dist/types/components/overlay/clipboard.utils.d.ts +3 -0
  32. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +4 -3
  33. package/dist/types/components/revoGrid/revo-grid.d.ts +4 -4
  34. package/dist/types/components.d.ts +14 -14
  35. package/dist/types/types/interfaces.d.ts +8 -0
  36. package/hydrate/index.js +103 -28
  37. package/hydrate/index.mjs +103 -28
  38. package/package.json +1 -1
  39. package/readme.md +20 -1
  40. package/standalone/column.service.js +1 -1
  41. 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);
@@ -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-CHyc9aCK.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');
@@ -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-CHyc9aCK.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');
@@ -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,
@@ -64,7 +64,7 @@ export class RevoGridComponent {
64
64
  this.rowSize = 0;
65
65
  /** Indicates default column size. */
66
66
  this.colSize = 100;
67
- /** When true, user can range selection. */
67
+ /** When true, user can select a cell range. Required for range-based clipboard fill. */
68
68
  this.range = false;
69
69
  /** When true, grid in read only mode. */
70
70
  this.readonly = false;
@@ -76,7 +76,7 @@ export class RevoGridComponent {
76
76
  this.noHorizontalScrollTransfer = false;
77
77
  /** When true cell focus appear. */
78
78
  this.canFocus = true;
79
- /** When true enable clipboard. */
79
+ /** When true enable clipboard. Can be boolean or clipboard config. */
80
80
  this.useClipboard = true;
81
81
  /**
82
82
  * Columns - defines an array of grid columns.
@@ -1202,7 +1202,7 @@ export class RevoGridComponent {
1202
1202
  "optional": false,
1203
1203
  "docs": {
1204
1204
  "tags": [],
1205
- "text": "When true, user can range selection."
1205
+ "text": "When true, user can select a cell range. Required for range-based clipboard fill."
1206
1206
  },
1207
1207
  "getter": false,
1208
1208
  "setter": false,
@@ -1294,15 +1294,22 @@ export class RevoGridComponent {
1294
1294
  "type": "boolean",
1295
1295
  "mutable": false,
1296
1296
  "complexType": {
1297
- "original": "boolean",
1298
- "resolved": "boolean",
1299
- "references": {}
1297
+ "original": "boolean | ClipboardConfig",
1298
+ "resolved": "ClipboardConfig | boolean",
1299
+ "references": {
1300
+ "ClipboardConfig": {
1301
+ "location": "import",
1302
+ "path": "@type",
1303
+ "id": "src/types/index.ts::ClipboardConfig",
1304
+ "referenceLocation": "ClipboardConfig"
1305
+ }
1306
+ }
1300
1307
  },
1301
1308
  "required": false,
1302
1309
  "optional": false,
1303
1310
  "docs": {
1304
1311
  "tags": [],
1305
- "text": "When true enable clipboard."
1312
+ "text": "When true enable clipboard. Can be boolean or clipboard config."
1306
1313
  },
1307
1314
  "getter": false,
1308
1315
  "setter": false,
@@ -428,6 +428,7 @@ function onLoad() {
428
428
 
429
429
  grid.readonly = false;
430
430
  grid.range = true;
431
+ grid.useClipboard = { rangeFill: true };
431
432
  grid.resize = true;
432
433
  grid.filter = true;
433
434
 
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { h, f as Build } from './index-Chp_81rd.js';
5
5
  import { n as DATA_ROW, w as DRAG_ICON_CLASS, x as DRAGGABLE_CLASS } from './dimension.helpers-CGKwSvw6.js';
6
- import { l as GROUP_EXPAND_BTN, m as GROUP_EXPAND_EVENT, G as GROUP_DEPTH, h as GROUP_EXPANDED, P as PSEUDO_GROUP_ITEM, O as isRowDragService, B as getCellDataParsed } from './column.service-CC_SD8W3.js';
6
+ import { l as GROUP_EXPAND_BTN, m as GROUP_EXPAND_EVENT, G as GROUP_DEPTH, h as GROUP_EXPANDED, P as PSEUDO_GROUP_ITEM, O as isRowDragService, B as getCellDataParsed } from './column.service-C6hByxPy.js';
7
7
 
8
8
  /**
9
9
  * Renders sorting direction and optional additive sorting rank.
@@ -1,14 +1,14 @@
1
1
  /*!
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
- import { J as reduce, g as getRange, K as baseEach, C as getColumnType, c as columnTypes, L as toInteger, u as isGrouping, t as getGroupingName, r as rowTypes, B as getCellDataParsed, A as getCellRaw, j as GROUP_COLUMN_PROP, I as getColumnByProp, h as GROUP_EXPANDED, x as getParsedGroup, y as isSameGroup, G as GROUP_DEPTH, e as PSEUDO_GROUP_ITEM_VALUE, d as PSEUDO_GROUP_ITEM_ID, o as GROUPING_ROW_TYPE, p as getSource, f as PSEUDO_GROUP_COLUMN, s as gatherGrouping, m as GROUP_EXPAND_EVENT, v as isGroupingColumn, q as getExpanded, E as isColGrouping } from './column.service-CC_SD8W3.js';
4
+ import { J as reduce, g as getRange, K as baseEach, C as getColumnType, c as columnTypes, L as toInteger, u as isGrouping, t as getGroupingName, r as rowTypes, B as getCellDataParsed, A as getCellRaw, j as GROUP_COLUMN_PROP, I as getColumnByProp, h as GROUP_EXPANDED, x as getParsedGroup, y as isSameGroup, G as GROUP_DEPTH, e as PSEUDO_GROUP_ITEM_VALUE, d as PSEUDO_GROUP_ITEM_ID, o as GROUPING_ROW_TYPE, p as getSource, f as PSEUDO_GROUP_COLUMN, s as gatherGrouping, m as GROUP_EXPAND_EVENT, v as isGroupingColumn, q as getExpanded, E as isColGrouping } from './column.service-C6hByxPy.js';
5
5
  import { K as createStore, l as setStore, i as calculateDimensionData, L as identity, N as isArray, b as getSourceItem, g as getPhysical, e as setItems, j as getItemByPosition } from './dimension.helpers-CGKwSvw6.js';
6
6
  import { j as calculateRowHeaderSize } from './viewport.store-_c579YyM.js';
7
7
  import { g as getScrollbarSize, t as timeout } from './index-Db3qZoW5.js';
8
8
  import { h } from './index-Chp_81rd.js';
9
9
  import { b as FILTER_PROP, i as isFilterBtn } from './filter.button-C8XTWPU2.js';
10
10
  import { d as debounce } from './debounce-PCRWZliA.js';
11
- import { O as ON_COLUMN_CLICK, d as dispatch } from './header-cell-renderer-B-LX2sgu.js';
11
+ import { O as ON_COLUMN_CLICK, d as dispatch } from './header-cell-renderer-BMmXRsd_.js';
12
12
 
13
13
  function calculateRealSize({ count, originItemSize, sizes, }) {
14
14
  const safeCount = Math.max(0, count);