@revolist/revogrid 4.22.1 → 4.23.1

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 (125) hide show
  1. package/dist/cjs/{cell-renderer-BQdEGQXP.js → cell-renderer-Dcz022q7.js} +9 -3
  2. package/dist/cjs/{column.drag.plugin-RDjQhKCH.js → column.drag.plugin-DJueWxN_.js} +391 -256
  3. package/dist/cjs/{column.service-DXYMehqK.js → column.service-C1Qvcf5l.js} +10 -1
  4. package/dist/cjs/{dimension.helpers-CiiNnlLa.js → dimension.helpers-B9HgANnM.js} +14 -145
  5. package/dist/cjs/{edit.utils-CecCfA4E.js → edit.utils-pKeiYFLJ.js} +1 -1
  6. package/dist/cjs/{header-cell-renderer-DGyBrK8I.js → header-cell-renderer-QrcXXSkF.js} +1 -1
  7. package/dist/cjs/index-DxaSE5uZ.js +136 -0
  8. package/dist/cjs/index.cjs.js +37 -32
  9. package/dist/cjs/revo-grid.cjs.entry.js +124 -18
  10. package/dist/cjs/revogr-attribution_7.cjs.entry.js +43 -25
  11. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +10 -8
  12. package/dist/cjs/revogr-data_4.cjs.entry.js +74 -32
  13. package/dist/cjs/revogr-filter-panel.cjs.entry.js +2 -1
  14. package/dist/cjs/{text-editor-DnLZW1a-.js → text-editor-B4W-m-r-.js} +3 -3
  15. package/dist/cjs/{throttle-CfgQFkfR.js → throttle-BCwEuJJq.js} +59 -24
  16. package/dist/cjs/viewport.helpers-BND76K2j.js +140 -0
  17. package/dist/cjs/{viewport.store-q6YdR9mg.js → viewport.store-BlKQ4x9H.js} +16 -16
  18. package/dist/collection/components/data/revogr-data.js +5 -3
  19. package/dist/collection/components/header/header-group-renderer.js +1 -1
  20. package/dist/collection/components/header/header-renderer.js +1 -1
  21. package/dist/collection/components/header/revogr-header-style.css +13 -3
  22. package/dist/collection/components/header/revogr-header.js +53 -17
  23. package/dist/collection/components/order/order-row.service.js +6 -5
  24. package/dist/collection/components/overlay/keyboard.service.js +23 -1
  25. package/dist/collection/components/overlay/selection.utils.js +8 -6
  26. package/dist/collection/components/revoGrid/revo-grid.js +69 -5
  27. package/dist/collection/components/revoGrid/viewport.service.js +2 -1
  28. package/dist/collection/components/scroll/revogr-viewport-scroll.js +10 -6
  29. package/dist/collection/components/scrollable/revogr-scroll-virtual.js +4 -10
  30. package/dist/collection/plugins/filter/filter.panel.js +2 -1
  31. package/dist/collection/plugins/filter/filter.plugin.js +11 -4
  32. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +25 -1
  33. package/dist/collection/plugins/groupingRow/grouping.service.js +9 -0
  34. package/dist/collection/plugins/moveColumn/column.drag.plugin.js +4 -4
  35. package/dist/collection/plugins/sorting/sorting.func.js +173 -15
  36. package/dist/collection/plugins/sorting/sorting.plugin.js +167 -84
  37. package/dist/collection/plugins/sorting/sorting.sign.js +7 -1
  38. package/dist/collection/serve/controller.js +98 -37
  39. package/dist/collection/serve/data.js +273 -144
  40. package/dist/collection/services/dimension.provider.js +16 -1
  41. package/dist/collection/services/local.scroll.service.js +59 -24
  42. package/dist/collection/services/scroll.dimension.helpers.js +83 -0
  43. package/dist/collection/services/selection.store.connector.js +30 -4
  44. package/dist/collection/store/dimension/dimension.recalculate.plugin.js +22 -9
  45. package/dist/collection/store/dimension/dimension.store.js +4 -2
  46. package/dist/collection/store/vp/viewport.helpers.js +9 -0
  47. package/dist/collection/store/vp/viewport.store.js +5 -16
  48. package/dist/collection/utils/store.utils.js +3 -3
  49. package/dist/{revo-grid/cell-renderer-CALsEsnh.js → esm/cell-renderer-BtN-NGCk.js} +9 -3
  50. package/dist/esm/{column.drag.plugin-Dy5ztusn.js → column.drag.plugin-DCZW62Uc.js} +388 -255
  51. package/dist/esm/{column.service-CCvAi5l4.js → column.service-CC_SD8W3.js} +10 -1
  52. package/dist/{revo-grid/debounce-BfO9dz9v.js → esm/debounce-PCRWZliA.js} +1 -1
  53. package/dist/{revo-grid/dimension.helpers-DmIvjIa7.js → esm/dimension.helpers-CGKwSvw6.js} +7 -128
  54. package/dist/esm/{edit.utils-DYN6XZh8.js → edit.utils-Dnnbd0xG.js} +1 -1
  55. package/dist/{revo-grid/header-cell-renderer-DU8wKAbg.js → esm/header-cell-renderer-BsvUQ8GS.js} +1 -1
  56. package/dist/esm/index-Db3qZoW5.js +127 -0
  57. package/dist/esm/index.js +11 -10
  58. package/dist/esm/revo-grid.entry.js +123 -17
  59. package/dist/esm/revogr-attribution_7.entry.js +42 -24
  60. package/dist/esm/revogr-clipboard_3.entry.js +11 -9
  61. package/dist/esm/revogr-data_4.entry.js +75 -33
  62. package/dist/esm/revogr-filter-panel.entry.js +3 -2
  63. package/dist/esm/{text-editor-DpCnd6Fq.js → text-editor-C3RUSwH5.js} +2 -2
  64. package/dist/esm/{throttle-ERvyruXb.js → throttle-CaUDyxyU.js} +60 -25
  65. package/dist/esm/viewport.helpers-CoCAvmZs.js +133 -0
  66. package/dist/{revo-grid/viewport.store-CFjDW-3l.js → esm/viewport.store-COAfzAyu.js} +15 -17
  67. package/dist/{esm/cell-renderer-CALsEsnh.js → revo-grid/cell-renderer-BtN-NGCk.js} +9 -3
  68. package/dist/revo-grid/{column.drag.plugin-Dy5ztusn.js → column.drag.plugin-DCZW62Uc.js} +388 -255
  69. package/dist/revo-grid/{column.service-CCvAi5l4.js → column.service-CC_SD8W3.js} +10 -1
  70. package/dist/{esm/debounce-BfO9dz9v.js → revo-grid/debounce-PCRWZliA.js} +1 -1
  71. package/dist/{esm/dimension.helpers-DmIvjIa7.js → revo-grid/dimension.helpers-CGKwSvw6.js} +7 -128
  72. package/dist/revo-grid/{edit.utils-DYN6XZh8.js → edit.utils-Dnnbd0xG.js} +1 -1
  73. package/dist/{esm/header-cell-renderer-DU8wKAbg.js → revo-grid/header-cell-renderer-BsvUQ8GS.js} +1 -1
  74. package/dist/revo-grid/index-Db3qZoW5.js +127 -0
  75. package/dist/revo-grid/index.esm.js +11 -10
  76. package/dist/revo-grid/revo-grid.entry.js +123 -17
  77. package/dist/revo-grid/revogr-attribution_7.entry.js +42 -24
  78. package/dist/revo-grid/revogr-clipboard_3.entry.js +11 -9
  79. package/dist/revo-grid/revogr-data_4.entry.js +75 -33
  80. package/dist/revo-grid/revogr-filter-panel.entry.js +3 -2
  81. package/dist/revo-grid/{text-editor-DpCnd6Fq.js → text-editor-C3RUSwH5.js} +2 -2
  82. package/dist/revo-grid/{throttle-ERvyruXb.js → throttle-CaUDyxyU.js} +60 -25
  83. package/dist/revo-grid/viewport.helpers-CoCAvmZs.js +133 -0
  84. package/dist/{esm/viewport.store-CFjDW-3l.js → revo-grid/viewport.store-COAfzAyu.js} +15 -17
  85. package/dist/types/components/header/header-group-renderer.d.ts +2 -0
  86. package/dist/types/components/header/header-renderer.d.ts +1 -0
  87. package/dist/types/components/header/revogr-header.d.ts +2 -0
  88. package/dist/types/components/overlay/keyboard.service.d.ts +5 -0
  89. package/dist/types/components/revoGrid/revo-grid.d.ts +12 -0
  90. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +8 -0
  91. package/dist/types/plugins/sorting/sorting.func.d.ts +25 -2
  92. package/dist/types/plugins/sorting/sorting.plugin.d.ts +84 -9
  93. package/dist/types/plugins/sorting/sorting.sign.d.ts +5 -1
  94. package/dist/types/plugins/sorting/sorting.types.d.ts +46 -1
  95. package/dist/types/services/local.scroll.service.d.ts +10 -2
  96. package/dist/types/services/scroll.dimension.helpers.d.ts +20 -0
  97. package/dist/types/services/selection.store.connector.d.ts +6 -0
  98. package/dist/types/store/vp/viewport.helpers.d.ts +2 -0
  99. package/dist/types/types/interfaces.d.ts +11 -0
  100. package/dist/types/types/selection.d.ts +13 -0
  101. package/hydrate/index.js +795 -383
  102. package/hydrate/index.mjs +795 -383
  103. package/package.json +1 -1
  104. package/standalone/column.service.js +1 -1
  105. package/standalone/data.store.js +1 -1
  106. package/standalone/debounce.js +1 -1
  107. package/standalone/dimension.helpers.js +1 -1
  108. package/standalone/index.js +1 -1
  109. package/standalone/local.scroll.timer.js +1 -1
  110. package/standalone/revo-grid.js +1 -1
  111. package/standalone/revogr-data2.js +1 -1
  112. package/standalone/revogr-filter-panel.js +1 -1
  113. package/standalone/revogr-header2.js +1 -1
  114. package/standalone/revogr-order-editor2.js +1 -1
  115. package/standalone/revogr-overlay-selection2.js +1 -1
  116. package/standalone/revogr-row-headers.js +1 -1
  117. package/standalone/revogr-row-headers2.js +1 -1
  118. package/standalone/revogr-scroll-virtual2.js +1 -1
  119. package/standalone/revogr-viewport-scroll2.js +1 -1
  120. package/standalone/selection.utils.js +1 -1
  121. package/standalone/throttle.js +1 -1
  122. package/standalone/toNumber.js +1 -1
  123. package/dist/cjs/viewport.helpers-BAovztDd.js +0 -58
  124. package/dist/esm/viewport.helpers-VXhsJZtn.js +0 -52
  125. package/dist/revo-grid/viewport.helpers-VXhsJZtn.js +0 -52
@@ -3,8 +3,8 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var edit_utils = require('./edit.utils-CecCfA4E.js');
7
- var dimension_helpers = require('./dimension.helpers-CiiNnlLa.js');
6
+ var edit_utils = require('./edit.utils-pKeiYFLJ.js');
7
+ var index = require('./index-DxaSE5uZ.js');
8
8
 
9
9
  class TextEditor {
10
10
  constructor(data, saveCallback) {
@@ -20,7 +20,7 @@ class TextEditor {
20
20
  async componentDidRender() {
21
21
  var _a;
22
22
  if (this.editInput) {
23
- await dimension_helpers.timeout();
23
+ await index.timeout();
24
24
  (_a = this.editInput) === null || _a === void 0 ? void 0 : _a.focus();
25
25
  }
26
26
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var dimension_helpers = require('./dimension.helpers-CiiNnlLa.js');
6
+ var viewport_helpers = require('./viewport.helpers-BND76K2j.js');
7
7
  var debounce = require('./debounce-CcpHiH2p.js');
8
8
 
9
9
  const initialParams = {
@@ -18,10 +18,11 @@ const NO_COORDINATE = -1;
18
18
  * return full size
19
19
  */
20
20
  function getContentSize(contentSize, clientSize, virtualSize = 0) {
21
- if (virtualSize > contentSize) {
22
- return 0;
23
- }
24
- return contentSize + (virtualSize ? clientSize - virtualSize : 0);
21
+ return viewport_helpers.getScrollDimension({
22
+ contentSize,
23
+ clientSize,
24
+ virtualSize,
25
+ }).physicalContentSize;
25
26
  }
26
27
  class LocalScrollService {
27
28
  constructor(cfg) {
@@ -35,14 +36,20 @@ class LocalScrollService {
35
36
  rgRow: NO_COORDINATE,
36
37
  rgCol: NO_COORDINATE,
37
38
  };
39
+ this.previousLogicalScroll = {
40
+ rgRow: 0,
41
+ rgCol: 0,
42
+ };
38
43
  this.params = {
39
44
  rgRow: Object.assign({}, initialParams),
40
45
  rgCol: Object.assign({}, initialParams),
41
46
  };
42
47
  }
43
48
  setParams(params, dimension) {
44
- const virtualContentSize = getContentSize(params.contentSize, params.clientSize, params.virtualSize);
45
- this.params[dimension] = Object.assign(Object.assign({}, params), { maxSize: virtualContentSize - params.clientSize, virtualContentSize });
49
+ const scrollDimension = viewport_helpers.getScrollDimension(params);
50
+ const virtualContentSize = scrollDimension.physicalContentSize;
51
+ this.params[dimension] = Object.assign(Object.assign({}, params), { maxSize: virtualContentSize - params.clientSize, virtualContentSize,
52
+ scrollDimension });
46
53
  }
47
54
  // apply scroll values after scroll done
48
55
  async setScroll(e) {
@@ -62,16 +69,27 @@ class LocalScrollService {
62
69
  await frameAnimation;
63
70
  const params = this.getParams(e.dimension);
64
71
  e.coordinate = Math.ceil(e.coordinate);
65
- this.previousScroll[e.dimension] = this.wrapCoordinate(e.coordinate, params);
72
+ this.previousLogicalScroll[e.dimension] = this.wrapLogicalCoordinate(e.coordinate, params);
73
+ const physicalCoordinate = this.toPhysicalCoordinate(e.coordinate, params);
74
+ this.previousScroll[e.dimension] = this.wrapPhysicalCoordinate(physicalCoordinate, params);
66
75
  this.preventArtificialScroll[e.dimension] = null;
67
- this.cfg.applyScroll(Object.assign(Object.assign({}, e), { coordinate: params.virtualSize
68
- ? this.convert(e.coordinate, params, false)
69
- : e.coordinate }));
76
+ this.cfg.applyScroll(Object.assign(Object.assign({}, e), { coordinate: physicalCoordinate }));
70
77
  }
71
78
  catch (id) {
72
79
  window.cancelAnimationFrame(id);
73
80
  }
74
81
  }
82
+ async setScrollByDelta(e, currentPhysicalCoordinate) {
83
+ var _a;
84
+ const params = this.getParams(e.dimension);
85
+ const baseCoordinate = this.previousScroll[e.dimension] === NO_COORDINATE
86
+ ? this.toLogicalCoordinate(currentPhysicalCoordinate, params)
87
+ : this.previousLogicalScroll[e.dimension];
88
+ const coordinate = this.wrapLogicalCoordinate(baseCoordinate + ((_a = e.delta) !== null && _a !== void 0 ? _a : 0), params);
89
+ const nextEvent = Object.assign(Object.assign({}, e), { coordinate });
90
+ await this.setScroll(nextEvent);
91
+ return nextEvent;
92
+ }
75
93
  /**
76
94
  * On scroll event started
77
95
  */
@@ -84,21 +102,21 @@ class LocalScrollService {
84
102
  return;
85
103
  }
86
104
  const param = this.getParams(dimension);
105
+ const logicalCoordinate = this.toLogicalScrollCoordinate(coordinate, dimension, param, delta);
87
106
  // let component know about scroll event started
88
107
  this.cfg.runScroll({
89
108
  dimension: dimension,
90
- coordinate: param.virtualSize
91
- ? this.convert(coordinate, param)
92
- : coordinate,
109
+ coordinate: logicalCoordinate,
93
110
  delta,
94
111
  outside,
95
112
  });
113
+ this.previousLogicalScroll[dimension] = logicalCoordinate;
96
114
  }
97
115
  getParams(dimension) {
98
116
  return this.params[dimension];
99
117
  }
100
118
  // check if scroll outside of region to avoid looping
101
- wrapCoordinate(c, param) {
119
+ wrapPhysicalCoordinate(c, param) {
102
120
  if (c < 0) {
103
121
  return NO_COORDINATE;
104
122
  }
@@ -107,22 +125,39 @@ class LocalScrollService {
107
125
  }
108
126
  return c;
109
127
  }
128
+ wrapLogicalCoordinate(c, param) {
129
+ var _a, _b;
130
+ if (c < 0) {
131
+ return 0;
132
+ }
133
+ return Math.min(c, (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.logicalScrollSize) !== null && _b !== void 0 ? _b : c);
134
+ }
110
135
  // prevent already started scroll, performance optimization
111
136
  cancelScroll(dimension) {
112
137
  var _a, _b;
113
138
  (_b = (_a = this.preventArtificialScroll)[dimension]) === null || _b === void 0 ? void 0 : _b.call(_a);
114
139
  this.preventArtificialScroll[dimension] = null;
115
140
  }
116
- /* convert virtual to real and back, scale range */
117
- convert(pos, param, toReal = true) {
118
- var _a;
119
- const minRange = param.clientSize;
120
- const from = [0, ((_a = param.virtualContentSize) !== null && _a !== void 0 ? _a : minRange) - minRange];
121
- const to = [0, param.contentSize - param.virtualSize];
122
- if (toReal) {
123
- return dimension_helpers.scaleValue(pos, from, to);
141
+ toLogicalScrollCoordinate(coordinate, dimension, param, delta) {
142
+ const scrollDimension = param.scrollDimension;
143
+ if (!scrollDimension) {
144
+ return coordinate;
145
+ }
146
+ if (typeof delta === 'number' && scrollDimension.isCompressed) {
147
+ const base = this.previousScroll[dimension] === NO_COORDINATE
148
+ ? scrollDimension.toLogicalCoordinate(coordinate - delta)
149
+ : this.previousLogicalScroll[dimension];
150
+ return scrollDimension.toLogicalCoordinate(scrollDimension.toPhysicalCoordinate(base + delta));
124
151
  }
125
- return dimension_helpers.scaleValue(pos, to, from);
152
+ return scrollDimension.toLogicalCoordinate(coordinate);
153
+ }
154
+ toPhysicalCoordinate(coordinate, param) {
155
+ var _a, _b;
156
+ return (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.toPhysicalCoordinate(coordinate)) !== null && _b !== void 0 ? _b : coordinate;
157
+ }
158
+ toLogicalCoordinate(coordinate, param) {
159
+ var _a, _b;
160
+ return (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.toLogicalCoordinate(coordinate)) !== null && _b !== void 0 ? _b : coordinate;
126
161
  }
127
162
  }
128
163
 
@@ -0,0 +1,140 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ 'use strict';
5
+
6
+ const FALLBACK_MAX_SCROLL_SIZE = 16000000;
7
+ const SCROLL_SIZE_GUARD = 1000000;
8
+ let detectedMaxScrollSize;
9
+ function getMaxScrollSize(doc = typeof document === 'undefined' ? undefined : document) {
10
+ if (typeof detectedMaxScrollSize === 'number') {
11
+ return detectedMaxScrollSize;
12
+ }
13
+ const body = doc === null || doc === void 0 ? void 0 : doc.body;
14
+ if (body) {
15
+ const ownerDocument = body.ownerDocument;
16
+ const element = ownerDocument.createElement('div');
17
+ element.style.cssText = [
18
+ 'height:1px',
19
+ 'left:-10000px',
20
+ 'overflow:scroll',
21
+ 'position:absolute',
22
+ 'top:-10000px',
23
+ 'visibility:hidden',
24
+ 'width:1px',
25
+ ].join(';');
26
+ const content = ownerDocument.createElement('div');
27
+ content.style.height = `${FALLBACK_MAX_SCROLL_SIZE * 4}px`;
28
+ element.appendChild(content);
29
+ body.appendChild(element);
30
+ detectedMaxScrollSize = Math.max(0, Math.min(element.scrollHeight, FALLBACK_MAX_SCROLL_SIZE * 4) - SCROLL_SIZE_GUARD);
31
+ element.remove();
32
+ if (detectedMaxScrollSize > SCROLL_SIZE_GUARD) {
33
+ return detectedMaxScrollSize;
34
+ }
35
+ detectedMaxScrollSize = FALLBACK_MAX_SCROLL_SIZE;
36
+ return detectedMaxScrollSize;
37
+ }
38
+ return FALLBACK_MAX_SCROLL_SIZE;
39
+ }
40
+ function getScrollDimension({ contentSize, clientSize, virtualSize = 0, maxScrollSize = getMaxScrollSize(), }) {
41
+ const safeContentSize = Math.max(0, maxScrollSize - SCROLL_SIZE_GUARD);
42
+ const size = Math.max(0, contentSize);
43
+ const client = Math.max(0, clientSize);
44
+ const viewport = Math.max(0, virtualSize || client);
45
+ const logicalScrollSize = Math.max(0, size - viewport);
46
+ const maxPhysicalScrollSize = Math.max(0, safeContentSize - client);
47
+ const physicalScrollSize = Math.min(logicalScrollSize, maxPhysicalScrollSize);
48
+ const physicalContentSize = client + physicalScrollSize;
49
+ const isCompressed = logicalScrollSize > physicalScrollSize && physicalScrollSize > 0;
50
+ const clampLogical = (coordinate) => Math.min(Math.max(0, coordinate || 0), logicalScrollSize);
51
+ const clampPhysical = (coordinate) => Math.min(Math.max(0, coordinate || 0), physicalScrollSize);
52
+ const toLogicalCoordinate = (coordinate) => {
53
+ if (!logicalScrollSize || !physicalScrollSize) {
54
+ return 0;
55
+ }
56
+ if (!isCompressed) {
57
+ return clampLogical(coordinate);
58
+ }
59
+ return clampLogical((clampPhysical(coordinate) / physicalScrollSize) * logicalScrollSize);
60
+ };
61
+ const toPhysicalCoordinate = (coordinate) => {
62
+ if (!logicalScrollSize || !physicalScrollSize) {
63
+ return 0;
64
+ }
65
+ if (!isCompressed) {
66
+ return clampPhysical(coordinate);
67
+ }
68
+ return clampPhysical((clampLogical(coordinate) / logicalScrollSize) * physicalScrollSize);
69
+ };
70
+ return {
71
+ contentSize: size,
72
+ clientSize: client,
73
+ viewportSize: viewport,
74
+ physicalContentSize,
75
+ logicalScrollSize,
76
+ physicalScrollSize,
77
+ isCompressed,
78
+ toLogicalCoordinate,
79
+ toPhysicalCoordinate,
80
+ getRenderOffset(coordinate) {
81
+ const logical = clampLogical(coordinate);
82
+ return logical - toPhysicalCoordinate(logical);
83
+ },
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Collects data for pinned columns in the required @ViewportProps format.
89
+ */
90
+ /**
91
+ * Represents the slot names for the viewport slots.
92
+ */
93
+ const HEADER_SLOT = 'header'; // Slot name for the header slot
94
+ const FOOTER_SLOT = 'footer'; // Slot name for the footer slot
95
+ const CONTENT_SLOT = 'content'; // Slot name for the content slot
96
+ const DATA_SLOT = 'data'; // Slot name for the data slot
97
+ /**
98
+ * Returns the last visible cell in the viewport for a given row type.
99
+ * Coordinates are not zero-based and are relative to the viewport.
100
+ * If needed to be zero-based they can be adjusted by subtracting 1.
101
+ */
102
+ function getLastCell(data, rowType) {
103
+ // Get the last visible column count from the viewport column data.
104
+ const lastVisibleColumnCount = data.viewports[data.colType].store.get('realCount');
105
+ // Get the last visible row count for the given row type from the viewport column data.
106
+ const lastVisibleRowCount = data.viewports[rowType].store.get('realCount');
107
+ // Return the last visible cell with the last visible column count and row count.
108
+ return {
109
+ x: lastVisibleColumnCount,
110
+ y: lastVisibleRowCount,
111
+ };
112
+ }
113
+ function viewportDataPartition(data, type, slot, fixed) {
114
+ return {
115
+ colData: data.colStore,
116
+ viewportCol: data.viewports[data.colType].store,
117
+ viewportRow: data.viewports[type].store,
118
+ /**
119
+ * lastCell is the last real coordinate + 1, saved to selection store
120
+ */
121
+ lastCell: getLastCell(data, type),
122
+ slot,
123
+ type,
124
+ canDrag: !fixed,
125
+ position: data.position,
126
+ dataStore: data.rowStores[type].store,
127
+ dimensionCol: data.dimensions[data.colType].store,
128
+ dimensionRow: data.dimensions[type].store,
129
+ style: fixed
130
+ ? { height: `${data.dimensions[type].store.get('realSize')}px` }
131
+ : undefined,
132
+ };
133
+ }
134
+
135
+ exports.CONTENT_SLOT = CONTENT_SLOT;
136
+ exports.DATA_SLOT = DATA_SLOT;
137
+ exports.FOOTER_SLOT = FOOTER_SLOT;
138
+ exports.HEADER_SLOT = HEADER_SLOT;
139
+ exports.getScrollDimension = getScrollDimension;
140
+ exports.viewportDataPartition = viewportDataPartition;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var dimension_helpers = require('./dimension.helpers-CiiNnlLa.js');
6
+ var dimension_helpers = require('./dimension.helpers-B9HgANnM.js');
7
7
 
8
8
  const LETTER_BLOCK_SIZE = 10;
9
9
  const calculateRowHeaderSize = (itemsLength, rowHeaderColumn, minWidth = 50) => {
@@ -11,6 +11,15 @@ const calculateRowHeaderSize = (itemsLength, rowHeaderColumn, minWidth = 50) =>
11
11
  Math.max((itemsLength.toString().length + 1) * LETTER_BLOCK_SIZE, minWidth));
12
12
  };
13
13
 
14
+ function getViewportMaxCoordinate(dimension, viewportSize, frameOffset = 1) {
15
+ if (!viewportSize || dimension.realSize <= viewportSize) {
16
+ return 0;
17
+ }
18
+ return Math.max(0, dimension.realSize - viewportSize - dimension.originItemSize * frameOffset);
19
+ }
20
+ function clampViewportCoordinate(coordinate, dimension, viewportSize, frameOffset = 1) {
21
+ return Math.min(Math.max(0, coordinate), getViewportMaxCoordinate(dimension, viewportSize, frameOffset));
22
+ }
14
23
  /**
15
24
  * Update items based on new scroll position
16
25
  * If viewport wasn't changed fully simple recombination of positions
@@ -276,6 +285,8 @@ function initialState() {
276
285
  realCount: 0,
277
286
  // size of viewport in px
278
287
  clientSize: 0,
288
+ // logical-to-physical render offset used when scroll space is compressed
289
+ renderOffset: 0,
279
290
  };
280
291
  }
281
292
  /**
@@ -311,21 +322,8 @@ class ViewportStore {
311
322
  const outsize = singleOffsetInPx * 2;
312
323
  // math virtual size is based on visible area + 2 items outside of visible area
313
324
  const virtualSize = viewportSize + outsize;
314
- // expected no scroll if real size less than virtual size, position is 0
315
- let maxCoordinate = 0;
316
- // if there is nodes outside of viewport, max coordinate has to be adjusted
317
- if (dimension.realSize > viewportSize) {
318
- // max coordinate is real size minus virtual/rendered space
319
- maxCoordinate = dimension.realSize - viewportSize - singleOffsetInPx;
320
- }
321
- let pos = position;
322
- // limit position to max and min coordinates
323
- if (pos < 0) {
324
- pos = 0;
325
- }
326
- else if (pos > maxCoordinate) {
327
- pos = maxCoordinate;
328
- }
325
+ const maxCoordinate = getViewportMaxCoordinate(dimension, viewportSize, frameOffset);
326
+ let pos = clampViewportCoordinate(position, dimension, viewportSize, frameOffset);
329
327
  // store last coordinate for further restore on redraw
330
328
  this.lastCoordinate = pos;
331
329
  // actual position is less than first item start based on offset
@@ -406,10 +404,12 @@ class ViewportStore {
406
404
  exports.ViewportStore = ViewportStore;
407
405
  exports.addMissingItems = addMissingItems;
408
406
  exports.calculateRowHeaderSize = calculateRowHeaderSize;
407
+ exports.clampViewportCoordinate = clampViewportCoordinate;
409
408
  exports.getFirstItem = getFirstItem;
410
409
  exports.getItems = getItems;
411
410
  exports.getLastItem = getLastItem;
412
411
  exports.getUpdatedItemsByPosition = getUpdatedItemsByPosition;
412
+ exports.getViewportMaxCoordinate = getViewportMaxCoordinate;
413
413
  exports.isActiveRange = isActiveRange;
414
414
  exports.isActiveRangeOutsideLastItem = isActiveRangeOutsideLastItem;
415
415
  exports.recombineByOffset = recombineByOffset;
@@ -102,11 +102,13 @@ export class RevogrData {
102
102
  const depth = this.dataStore.get('groupingDepth');
103
103
  const groupingCustomRenderer = this.dataStore.get('groupingCustomRenderer');
104
104
  const groupDepth = this.columnService.hasGrouping ? depth : 0;
105
+ const rowRenderOffset = this.viewportRow.get('renderOffset') || 0;
106
+ const colRenderOffset = this.viewportCol.get('renderOffset') || 0;
105
107
  for (let rgRow of rows) {
106
108
  const dataItem = getSourceItem(this.dataStore, rgRow.itemIndex);
107
109
  // #region Grouping
108
110
  if (isGrouping(dataItem)) {
109
- const gmodel = Object.assign(Object.assign({}, rgRow), { index: rgRow.itemIndex, model: dataItem, groupingCustomRenderer,
111
+ const gmodel = Object.assign(Object.assign({}, rgRow), { start: rgRow.start - rowRenderOffset, index: rgRow.itemIndex, model: dataItem, groupingCustomRenderer,
110
112
  // Only show expand button if grouping is enabled and not in row headers
111
113
  hasExpand: this.columnService.hasGrouping && this.colType !== 'rowHeaders', columnItems: cols, providers: this.providers });
112
114
  rowsEls.push(h(GroupingRowRenderer, Object.assign({}, gmodel)));
@@ -129,7 +131,7 @@ export class RevogrData {
129
131
  [DATA_ROW]: rowProps.itemIndex,
130
132
  style: {
131
133
  width: `${columnProps.size}px`,
132
- transform: `translateX(${columnProps.start}px)`,
134
+ transform: `translateX(${columnProps.start - colRenderOffset}px)`,
133
135
  height: rowProps.size ? `${rowProps.size}px` : undefined,
134
136
  },
135
137
  };
@@ -157,7 +159,7 @@ export class RevogrData {
157
159
  if (this.rowHighlightPlugin.isRowFocused(rgRow.itemIndex)) {
158
160
  rowClass += ` ${ROW_FOCUSED_CLASS}`;
159
161
  }
160
- const row = (h(RowRenderer, { index: rgRow.itemIndex, rowClass: rowClass, size: rgRow.size, start: rgRow.start, groupingLevel: groupDepth || undefined }, cells));
162
+ const row = (h(RowRenderer, { index: rgRow.itemIndex, rowClass: rowClass, size: rgRow.size, start: rgRow.start - rowRenderOffset, groupingLevel: groupDepth || undefined }, cells));
161
163
  this.beforerowrender.emit({
162
164
  node: row,
163
165
  item: rgRow,
@@ -15,7 +15,7 @@ const HeaderGroupRenderer = (p) => {
15
15
  [HEADER_CLASS]: true,
16
16
  },
17
17
  style: {
18
- transform: `translateX(${p.start}px)`,
18
+ transform: `translateX(${p.start - (p.renderOffset || 0)}px)`,
19
19
  width: `${p.end - p.start}px`,
20
20
  },
21
21
  onResize: p.onResize,
@@ -25,7 +25,7 @@ const HeaderRenderer = (p) => {
25
25
  class: cellClass,
26
26
  style: {
27
27
  width: `${p.column.size}px`,
28
- transform: `translateX(${p.column.start}px)`,
28
+ transform: `translateX(${p.column.start - (p.renderOffset || 0)}px)`,
29
29
  },
30
30
  onResize: p.onResize,
31
31
  onDblClick(originalEvent) {
@@ -34,15 +34,25 @@ revogr-header .rgHeaderCell.align-right {
34
34
  revogr-header .rgHeaderCell.sortable {
35
35
  cursor: pointer;
36
36
  }
37
- revogr-header .rgHeaderCell i.asc:after, revogr-header .rgHeaderCell i.desc:after {
37
+ revogr-header .rgHeaderCell .sort-indicator {
38
+ display: inline-flex;
39
+ align-items: flex-start;
40
+ gap: 1px;
41
+ }
42
+ revogr-header .rgHeaderCell .sort-indicator i.asc:after, revogr-header .rgHeaderCell .sort-indicator i.desc:after {
38
43
  font-size: 13px;
39
44
  }
40
- revogr-header .rgHeaderCell i.asc:after {
45
+ revogr-header .rgHeaderCell .sort-indicator i.asc:after {
41
46
  content: "↑";
42
47
  }
43
- revogr-header .rgHeaderCell i.desc:after {
48
+ revogr-header .rgHeaderCell .sort-indicator i.desc:after {
44
49
  content: "↓";
45
50
  }
51
+ revogr-header .rgHeaderCell .sort-indicator .sort-order-index {
52
+ font-size: 10px;
53
+ line-height: 1;
54
+ top: 0;
55
+ }
46
56
  revogr-header .rgHeaderCell.active {
47
57
  z-index: 10;
48
58
  }
@@ -52,6 +52,7 @@ export class RevogrHeaderComponent {
52
52
  }
53
53
  renderHeaderColumns(cols, range) {
54
54
  const columnsToRender = [];
55
+ const renderOffset = this.viewportCol.get('renderOffset') || 0;
55
56
  for (let rgCol of cols) {
56
57
  const colData = this.colData[rgCol.itemIndex];
57
58
  const props = {
@@ -60,6 +61,7 @@ export class RevogrHeaderComponent {
60
61
  data: Object.assign(Object.assign({}, colData), { index: rgCol.itemIndex, providers: this.providers }),
61
62
  canFilter: !!this.columnFilter,
62
63
  canResize: this.canResize,
64
+ renderOffset,
63
65
  active: this.resizeHandler,
64
66
  additionalData: this.additionalData,
65
67
  onResize: e => this.onResize(e, rgCol.itemIndex),
@@ -95,37 +97,71 @@ export class RevogrHeaderComponent {
95
97
  ];
96
98
  }
97
99
  renderGroupColumn(group, level, visibleGroupRange) {
98
- var _a;
99
- const groupStartIndex = (_a = group.indexes[0]) !== null && _a !== void 0 ? _a : -1;
100
- if (groupStartIndex < 0) {
101
- return;
102
- }
103
- const groupEndIndex = groupStartIndex + group.indexes.length - 1;
104
- if (!visibleGroupRange ||
105
- !isGroupInVisibleRange(groupStartIndex, groupEndIndex, visibleGroupRange)) {
106
- return;
107
- }
108
- const groupStart = getItemByIndex(this.dimensionCol.state, groupStartIndex).start;
109
- const groupEnd = getItemByIndex(this.dimensionCol.state, groupEndIndex).end;
100
+ const groupRange = this.getGroupIndexRange(group);
101
+ const groupBounds = this.getGroupBounds(groupRange);
110
102
  const props = {
103
+ level,
111
104
  providers: this.providers,
112
- start: groupStart,
113
- end: groupEnd,
105
+ start: groupBounds.start,
106
+ end: groupBounds.end,
114
107
  group,
108
+ renderOffset: this.viewportCol.get('renderOffset') || 0,
115
109
  active: this.resizeHandler,
116
110
  canResize: this.canResize,
117
111
  additionalData: this.additionalData,
118
112
  onResize: e => {
119
113
  var _a;
120
- return this.onResizeGroup((_a = e.changedX) !== null && _a !== void 0 ? _a : 0, groupStartIndex, groupEndIndex);
114
+ return groupRange
115
+ ? this.onResizeGroup((_a = e.changedX) !== null && _a !== void 0 ? _a : 0, groupRange.startIndex, groupRange.endIndex)
116
+ : undefined;
121
117
  },
122
118
  };
123
119
  const event = this.beforeGroupHeaderRender.emit(props);
124
120
  if (event.defaultPrevented) {
125
121
  return;
126
122
  }
123
+ const renderRange = this.getGroupIndexRange(event.detail.group);
124
+ if (!renderRange ||
125
+ !visibleGroupRange ||
126
+ !isGroupInVisibleRange(renderRange.startIndex, renderRange.endIndex, visibleGroupRange)) {
127
+ return;
128
+ }
129
+ if (event.detail.onResize === props.onResize) {
130
+ event.detail.onResize = e => {
131
+ var _a;
132
+ return this.onResizeGroup((_a = e.changedX) !== null && _a !== void 0 ? _a : 0, renderRange.startIndex, renderRange.endIndex);
133
+ };
134
+ }
135
+ const renderBounds = this.getGroupBounds(renderRange);
136
+ if (event.detail.start === props.start) {
137
+ event.detail.start = renderBounds.start;
138
+ }
139
+ if (event.detail.end === props.end) {
140
+ event.detail.end = renderBounds.end;
141
+ }
127
142
  return h(GroupHeaderRenderer, Object.assign({ key: this.getGroupHeaderCellKey(event.detail.group, level) }, event.detail));
128
143
  }
144
+ getGroupIndexRange(group) {
145
+ var _a;
146
+ const startIndex = (_a = group.indexes[0]) !== null && _a !== void 0 ? _a : -1;
147
+ if (startIndex < 0) {
148
+ return;
149
+ }
150
+ const endIndex = group.indexes[group.indexes.length - 1];
151
+ return {
152
+ startIndex,
153
+ endIndex,
154
+ };
155
+ }
156
+ getGroupBounds(range) {
157
+ if (!range) {
158
+ return { start: 0, end: 0 };
159
+ }
160
+ return {
161
+ start: getItemByIndex(this.dimensionCol.state, range.startIndex).start,
162
+ end: getItemByIndex(this.dimensionCol.state, range.endIndex).end,
163
+ };
164
+ }
129
165
  getVisibleGroupRange() {
130
166
  const visibleColumns = this.viewportCol.get('items');
131
167
  if (!visibleColumns.length) {
@@ -579,7 +615,7 @@ export class RevogrHeaderComponent {
579
615
  },
580
616
  "complexType": {
581
617
  "original": "HeaderRenderProps",
582
- "resolved": "{ column: VirtualPositionItem; additionalData: any; data: ColumnTemplateProp<ColumnProp>; range?: RangeArea | null | undefined; canResize?: boolean | undefined; canFilter?: boolean | undefined; onResize?(e: ResizeEvent): void; onClick?(data: InitialHeaderClick): void; onDblClick?(data: InitialHeaderClick): void; } & Partial<Pick<ResizeProps, \"active\">>",
618
+ "resolved": "{ column: VirtualPositionItem; additionalData: any; data: ColumnTemplateProp<ColumnProp>; range?: RangeArea | null | undefined; canResize?: boolean | undefined; canFilter?: boolean | undefined; renderOffset?: number | undefined; onResize?(e: ResizeEvent): void; onClick?(data: InitialHeaderClick): void; onDblClick?(data: InitialHeaderClick): void; } & Partial<Pick<ResizeProps, \"active\">>",
583
619
  "references": {
584
620
  "HeaderRenderProps": {
585
621
  "location": "import",
@@ -601,7 +637,7 @@ export class RevogrHeaderComponent {
601
637
  },
602
638
  "complexType": {
603
639
  "original": "HeaderGroupRendererProps",
604
- "resolved": "{ start: number; end: number; group: Group; providers: ProvidersColumns<DimensionCols | \"rowHeaders\">; additionalData: any; canResize?: boolean | undefined; onResize?(e: ResizeEvent): void; } & Partial<Pick<ResizeProps, \"active\">>",
640
+ "resolved": "{ level: number; start: number; end: number; group: Group; providers: ProvidersColumns<DimensionCols | \"rowHeaders\">; additionalData: any; canResize?: boolean | undefined; renderOffset?: number | undefined; onResize?(e: ResizeEvent): void; } & Partial<Pick<ResizeProps, \"active\">>",
605
641
  "references": {
606
642
  "HeaderGroupRendererProps": {
607
643
  "location": "import",
@@ -51,11 +51,12 @@ export default class RowOrderService {
51
51
  getRow(y, { el, rows }) {
52
52
  const { top } = el.getBoundingClientRect();
53
53
  const topRelative = y - top;
54
- const rgRow = getItemByPosition(rows, topRelative);
54
+ const rowOffset = rows.renderOffset || 0;
55
+ const rgRow = getItemByPosition(rows, topRelative + rowOffset);
55
56
  const absolutePosition = {
56
57
  itemIndex: rgRow.itemIndex,
57
- start: rgRow.start + top,
58
- end: rgRow.end + top,
58
+ start: rgRow.start - rowOffset + top,
59
+ end: rgRow.end - rowOffset + top,
59
60
  };
60
61
  return absolutePosition;
61
62
  }
@@ -64,8 +65,8 @@ export default class RowOrderService {
64
65
  const { top, left } = el.getBoundingClientRect();
65
66
  const topRelative = y - top;
66
67
  const leftRelative = x - left;
67
- const rgRow = getItemByPosition(rows, topRelative);
68
- const rgCol = getItemByPosition(cols, leftRelative);
68
+ const rgRow = getItemByPosition(rows, topRelative + (rows.renderOffset || 0));
69
+ const rgCol = getItemByPosition(cols, leftRelative + (cols.renderOffset || 0));
69
70
  return { x: rgCol.itemIndex, y: rgRow.itemIndex };
70
71
  }
71
72
  }
@@ -4,6 +4,7 @@
4
4
  import { getRange } from "../../store/index";
5
5
  import { codesLetter, isAll, isClear, isCopy, isCut, isEnterKeyValue, isPaste, isShortcutModifier, isTab, timeout, RESIZE_INTERVAL, } from "../../utils";
6
6
  import { getCoordinate, isAfterLast, isBeforeFirst, } from "./selection.utils";
7
+ import { isEditInput } from "../editors/edit.utils";
7
8
  const DIRECTION_CODES = [
8
9
  codesLetter.TAB,
9
10
  codesLetter.ARROW_UP,
@@ -15,9 +16,29 @@ export class KeyboardService {
15
16
  constructor(sv) {
16
17
  this.sv = sv;
17
18
  }
19
+ /**
20
+ * Appends printable key input that arrives after edit mode was requested
21
+ * but before the editor input has mounted or received focus.
22
+ */
23
+ appendPendingEditValue(e) {
24
+ if (isShortcutModifier(e) ||
25
+ e.key.length !== 1 ||
26
+ (e.target instanceof HTMLElement && isEditInput(e.target))) {
27
+ return false;
28
+ }
29
+ const editCell = this.sv.selectionStore.get('edit');
30
+ if (typeof (editCell === null || editCell === void 0 ? void 0 : editCell.val) !== 'string') {
31
+ return false;
32
+ }
33
+ this.sv.selectionStore.set('edit', Object.assign(Object.assign({}, editCell), { val: `${editCell.val}${e.key}` }));
34
+ return true;
35
+ }
18
36
  async keyDown(e, canRange, isEditMode, { range, focus }) {
19
37
  // IF EDIT MODE
20
38
  if (isEditMode) {
39
+ if (this.appendPendingEditValue(e)) {
40
+ return;
41
+ }
21
42
  switch (e.code) {
22
43
  case codesLetter.ESCAPE:
23
44
  this.sv.cancel();
@@ -111,7 +132,8 @@ export class KeyboardService {
111
132
  }
112
133
  const eData = this.sv.getData();
113
134
  if (isMulti) {
114
- if (isAfterLast(data.end, eData.lastCell) || isBeforeFirst(data.start)) {
135
+ const isOutOfBounds = [data.start, data.end].some(cell => isAfterLast(cell, eData.lastCell) || isBeforeFirst(cell));
136
+ if (isOutOfBounds) {
115
137
  return false;
116
138
  }
117
139
  const range = getRange(data.start, data.end);