@revolist/revogrid 4.26.2 → 4.27.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 (130) hide show
  1. package/dist/cjs/{cell-renderer-Cf2Pu4S0.js → cell-renderer-BDIx0xys.js} +3 -3
  2. package/dist/cjs/{column.service-C7p5eC5V.js → column.service-D-ENzqyb.js} +5 -3
  3. package/dist/cjs/{dimension.helpers-CgHhnN1d.js → dimension.helpers-CptesQOZ.js} +52 -8
  4. package/dist/cjs/{edit.utils-rAcGublN.js → edit.utils-CBAbQhGP.js} +1 -1
  5. package/dist/cjs/{header-cell-renderer-DHClfIto.js → header-cell-renderer-B5Y4fdZC.js} +1 -1
  6. package/dist/cjs/{index--FdNLz1Z.js → index-BVESmpqW.js} +1 -1
  7. package/dist/cjs/index.cjs.js +72 -55
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/cjs/revo-grid.cjs.entry.js +131 -86
  10. package/dist/cjs/revo-grid.cjs.js +1 -1
  11. package/dist/cjs/revogr-attribution_7.cjs.entry.js +51 -19
  12. package/dist/cjs/revogr-clipboard_3.cjs.entry.js +4 -4
  13. package/dist/cjs/revogr-data_4.cjs.entry.js +21 -15
  14. package/dist/cjs/revogr-filter-panel.cjs.entry.js +9 -9
  15. package/dist/cjs/{column.drag.plugin-CK5HADlW.js → row-resize.plugin-sK9_rcUN.js} +759 -86
  16. package/dist/cjs/{text-editor-F04kTx53.js → text-editor-CJyQaYei.js} +2 -2
  17. package/dist/cjs/{throttle-fV6BUmM7.js → throttle-BsaP4fgu.js} +3 -3
  18. package/dist/cjs/{viewport.store-B4Clk4m9.js → viewport.store-mhsdi61t.js} +1 -1
  19. package/dist/collection/components/data/revogr-data-style.css +11 -0
  20. package/dist/collection/components/data/revogr-data.js +14 -8
  21. package/dist/collection/components/header/revogr-header-style.css +1 -0
  22. package/dist/collection/components/overlay/keyboard.service.js +33 -3
  23. package/dist/collection/components/overlay/revogr-overlay-selection.js +12 -10
  24. package/dist/collection/components/revoGrid/plugin.service.js +2 -2
  25. package/dist/collection/components/revoGrid/revo-grid.js +80 -30
  26. package/dist/collection/components/revoGrid/viewport.scrolling.service.js +24 -13
  27. package/dist/collection/components/revoGrid/viewport.service.js +1 -1
  28. package/dist/collection/plugins/filter/filter.constants.js +9 -0
  29. package/dist/collection/plugins/filter/filter.panel.js +8 -8
  30. package/dist/collection/plugins/filter/filter.plugin.js +109 -10
  31. package/dist/collection/plugins/filter/filter.style.css +2 -0
  32. package/dist/collection/plugins/groupingRow/grouping.const.js +1 -0
  33. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +93 -56
  34. package/dist/collection/plugins/groupingRow/grouping.row.renderer.js +1 -1
  35. package/dist/collection/plugins/groupingRow/grouping.service.js +1 -1
  36. package/dist/collection/plugins/groupingRow/grouping.sorting.service.js +58 -0
  37. package/dist/collection/plugins/groupingRow/grouping.trimmed.service.js +5 -3
  38. package/dist/collection/plugins/index.js +1 -0
  39. package/dist/collection/plugins/row-resize/index.js +6 -0
  40. package/dist/collection/plugins/row-resize/row-resize.plugin.js +416 -0
  41. package/dist/collection/plugins/row-resize/row-resize.types.js +1 -0
  42. package/dist/collection/plugins/row-resize/row-resize.utils.js +55 -0
  43. package/dist/collection/plugins/sorting/sorting.plugin.js +16 -13
  44. package/dist/collection/plugins/wcag/index.js +5 -4
  45. package/dist/collection/serve/controller.js +1 -1
  46. package/dist/collection/services/data.provider.js +8 -2
  47. package/dist/collection/services/dimension.provider.js +17 -1
  48. package/dist/collection/services/local.scroll.timer.js +3 -3
  49. package/dist/collection/services/selection.store.connector.js +4 -2
  50. package/dist/collection/store/dataSource/data.pending.plugin.js +21 -0
  51. package/dist/collection/store/dataSource/data.store.js +25 -3
  52. package/dist/collection/store/dataSource/trimmed.plugin.js +9 -6
  53. package/dist/collection/store/dimension/dimension.trim.plugin.js +1 -3
  54. package/dist/collection/types/events.js +4 -1
  55. package/dist/collection/utils/column.utils.js +1 -1
  56. package/dist/esm/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
  57. package/dist/esm/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
  58. package/dist/{revo-grid/dimension.helpers-fl4HSSK9.js → esm/dimension.helpers-Cln9sALu.js} +52 -9
  59. package/dist/{revo-grid/edit.utils-4e9fsqOR.js → esm/edit.utils-3ZbhQCv_.js} +1 -1
  60. package/dist/esm/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
  61. package/dist/esm/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
  62. package/dist/esm/index.js +14 -11
  63. package/dist/esm/loader.js +1 -1
  64. package/dist/esm/revo-grid.entry.js +113 -68
  65. package/dist/esm/revo-grid.js +1 -1
  66. package/dist/esm/revogr-attribution_7.entry.js +51 -19
  67. package/dist/esm/revogr-clipboard_3.entry.js +4 -4
  68. package/dist/esm/revogr-data_4.entry.js +21 -15
  69. package/dist/esm/revogr-filter-panel.entry.js +9 -9
  70. package/dist/esm/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
  71. package/dist/{revo-grid/text-editor-DlMnLkRK.js → esm/text-editor-eHtrwvxH.js} +2 -2
  72. package/dist/{revo-grid/throttle-Cpk1LoGk.js → esm/throttle-3rhqdcLy.js} +3 -3
  73. package/dist/{revo-grid/viewport.store-BSXmsiZc.js → esm/viewport.store-DWMKRDSH.js} +1 -1
  74. package/dist/revo-grid/{cell-renderer-11cf-lu3.js → cell-renderer-D9ze8OJw.js} +3 -3
  75. package/dist/revo-grid/{column.service-Cfw3L0PN.js → column.service-pu_fdQ0S.js} +5 -4
  76. package/dist/{esm/dimension.helpers-fl4HSSK9.js → revo-grid/dimension.helpers-Cln9sALu.js} +52 -9
  77. package/dist/{esm/edit.utils-4e9fsqOR.js → revo-grid/edit.utils-3ZbhQCv_.js} +1 -1
  78. package/dist/revo-grid/{header-cell-renderer-Cqtg1ETB.js → header-cell-renderer-YCiVIQ2E.js} +1 -1
  79. package/dist/revo-grid/{index-D24ku9ej.js → index-BvMNbQyq.js} +1 -1
  80. package/dist/revo-grid/index.esm.js +14 -11
  81. package/dist/revo-grid/revo-grid.entry.js +113 -68
  82. package/dist/revo-grid/revo-grid.esm.js +1 -1
  83. package/dist/revo-grid/revogr-attribution_7.entry.js +51 -19
  84. package/dist/revo-grid/revogr-clipboard_3.entry.js +4 -4
  85. package/dist/revo-grid/revogr-data_4.entry.js +21 -15
  86. package/dist/revo-grid/revogr-filter-panel.entry.js +9 -9
  87. package/dist/revo-grid/{column.drag.plugin-DDBKeTGI.js → row-resize.plugin-DBOgjLdE.js} +748 -87
  88. package/dist/{esm/text-editor-DlMnLkRK.js → revo-grid/text-editor-eHtrwvxH.js} +2 -2
  89. package/dist/{esm/throttle-Cpk1LoGk.js → revo-grid/throttle-3rhqdcLy.js} +3 -3
  90. package/dist/{esm/viewport.store-BSXmsiZc.js → revo-grid/viewport.store-DWMKRDSH.js} +1 -1
  91. package/dist/types/components/data/revogr-data.d.ts +1 -0
  92. package/dist/types/components/overlay/keyboard.service.d.ts +6 -0
  93. package/dist/types/components/overlay/revogr-overlay-selection.d.ts +3 -1
  94. package/dist/types/components/revoGrid/revo-grid.d.ts +9 -1
  95. package/dist/types/components/revoGrid/viewport.scrolling.service.d.ts +3 -1
  96. package/dist/types/components.d.ts +23 -10
  97. package/dist/types/plugins/filter/filter.constants.d.ts +6 -0
  98. package/dist/types/plugins/filter/filter.plugin.d.ts +15 -0
  99. package/dist/types/plugins/groupingRow/grouping.const.d.ts +1 -0
  100. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +5 -7
  101. package/dist/types/plugins/groupingRow/grouping.sorting.service.d.ts +7 -0
  102. package/dist/types/plugins/groupingRow/grouping.trimmed.service.d.ts +9 -0
  103. package/dist/types/plugins/index.d.ts +1 -0
  104. package/dist/types/plugins/row-resize/index.d.ts +3 -0
  105. package/dist/types/plugins/row-resize/row-resize.plugin.d.ts +46 -0
  106. package/dist/types/plugins/row-resize/row-resize.types.d.ts +40 -0
  107. package/dist/types/plugins/row-resize/row-resize.utils.d.ts +14 -0
  108. package/dist/types/plugins/sorting/sorting.plugin.d.ts +5 -0
  109. package/dist/types/services/data.provider.d.ts +2 -0
  110. package/dist/types/services/dimension.provider.d.ts +7 -1
  111. package/dist/types/store/dataSource/data.pending.plugin.d.ts +9 -0
  112. package/dist/types/store/dataSource/data.store.d.ts +10 -0
  113. package/dist/types/store/dataSource/trimmed.plugin.d.ts +5 -0
  114. package/dist/types/types/events.d.ts +1 -1
  115. package/dist/types/types/interfaces.d.ts +3 -1
  116. package/hydrate/index.js +980 -191
  117. package/hydrate/index.mjs +980 -191
  118. package/package.json +1 -1
  119. package/readme.md +4 -1
  120. package/standalone/column.service.js +1 -1
  121. package/standalone/data.store.js +1 -1
  122. package/standalone/dimension.helpers.js +1 -1
  123. package/standalone/index.js +1 -1
  124. package/standalone/local.scroll.timer.js +1 -1
  125. package/standalone/revo-grid.js +1 -1
  126. package/standalone/revogr-data2.js +1 -1
  127. package/standalone/revogr-filter-panel.js +1 -1
  128. package/standalone/revogr-header2.js +1 -1
  129. package/standalone/revogr-overlay-selection2.js +1 -1
  130. package/standalone/revogr-row-headers2.js +1 -1
@@ -0,0 +1,416 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ import { getItemByIndex, getViewportMaxCoordinate, rowTypes } from "../../store/index";
5
+ import { BasePlugin } from "../base.plugin";
6
+ import { BEFORE_GROUPING_APPLY_EVENT, GROUP_EXPAND_EVENT, } from "../groupingRow/grouping.const";
7
+ import { clampRowResizeHeight, createRowResizePatch, getRowResizeIndexes, mergeRowResizeDefinitions, resolveRowResizeConfig, } from "./row-resize.utils";
8
+ export const ROW_RESIZE_HANDLE_CLASS = 'row-resize-handle';
9
+ export const BEFORE_ROW_RESIZE_EVENT = 'beforerowresize';
10
+ export const ROW_RESIZE_EVENT = 'rowresize';
11
+ export const AFTER_ROW_RESIZE_EVENT = 'afterrowresize';
12
+ export const ROW_RESIZE_CANCEL_EVENT = 'rowresizecancel';
13
+ export class RowResizePlugin extends BasePlugin {
14
+ constructor(revogrid, providers, config = {}) {
15
+ super(revogrid, providers);
16
+ this.enabled = false;
17
+ this.appliedDefinitionIndexes = new Map();
18
+ this.pendingBottomAnchor = false;
19
+ this.keepBottomAnchor = false;
20
+ this.rowDefinitionRemapQueued = false;
21
+ this.pendingSourceCounts = new Map();
22
+ this.previousBodyCursor = '';
23
+ this.decorateRow = ({ detail, }) => {
24
+ if (!this.enabled ||
25
+ (detail.colType !== 'rowHeaders' && !this.config.fullRow)) {
26
+ return;
27
+ }
28
+ const handle = this.h('div', {
29
+ 'key': `row-resize-${detail.rowType}-${detail.item.itemIndex}`,
30
+ 'class': { [ROW_RESIZE_HANDLE_CLASS]: true },
31
+ 'data-row-resize-index': detail.item.itemIndex,
32
+ 'aria-hidden': 'true',
33
+ 'onPointerDown': (event) => this.startResize(event, detail.rowType, detail.item.itemIndex),
34
+ });
35
+ detail.node.$children$ = [...(detail.node.$children$ || []), handle];
36
+ };
37
+ this.cancelForDataChange = () => this.cancel('data-change');
38
+ this.onPointerMove = (event) => {
39
+ const active = this.active;
40
+ if ((active === null || active === void 0 ? void 0 : active.pointerId) !== event.pointerId) {
41
+ return;
42
+ }
43
+ event.preventDefault();
44
+ active.lastEvent = event;
45
+ this.pendingHeight = clampRowResizeHeight(active.startHeight + event.clientY - active.startY, this.config);
46
+ if (this.animationFrame === undefined) {
47
+ const view = this.revogrid.ownerDocument.defaultView;
48
+ this.animationFrame = view === null || view === void 0 ? void 0 : view.requestAnimationFrame(() => {
49
+ this.animationFrame = undefined;
50
+ this.flushPendingResize();
51
+ });
52
+ }
53
+ };
54
+ this.onPointerUp = (event) => {
55
+ const active = this.active;
56
+ if ((active === null || active === void 0 ? void 0 : active.pointerId) !== event.pointerId) {
57
+ return;
58
+ }
59
+ event.preventDefault();
60
+ active.lastEvent = event;
61
+ this.pendingHeight = clampRowResizeHeight(active.startHeight + event.clientY - active.startY, this.config);
62
+ this.flushPendingResize();
63
+ if (this.active !== active) {
64
+ return;
65
+ }
66
+ const detail = this.eventDetail(active, event, active.currentHeight);
67
+ this.finishGesture();
68
+ this.commitResize(active);
69
+ this.emit(AFTER_ROW_RESIZE_EVENT, detail);
70
+ };
71
+ this.onPointerCancel = (event) => {
72
+ var _a;
73
+ if (((_a = this.active) === null || _a === void 0 ? void 0 : _a.pointerId) === event.pointerId) {
74
+ this.active.lastEvent = event;
75
+ this.cancel('pointercancel');
76
+ }
77
+ };
78
+ this.onKeyDown = (event) => {
79
+ if (event.key === 'Escape' && this.active) {
80
+ event.preventDefault();
81
+ this.cancel('escape');
82
+ }
83
+ };
84
+ this.onWindowBlur = () => this.cancel('blur');
85
+ this.updateBottomAnchorState = ({ detail, }) => {
86
+ if (detail.dimension !== 'rgRow') {
87
+ return;
88
+ }
89
+ this.keepBottomAnchor = this.isMainViewportAtBottom(detail.coordinate);
90
+ };
91
+ this.applyPendingBottomAnchor = () => {
92
+ if (!this.pendingBottomAnchor) {
93
+ return;
94
+ }
95
+ this.pendingBottomAnchor = false;
96
+ const dimension = this.providers.dimension.stores.rgRow.store;
97
+ // Scroll surfaces have slightly different client sizes. Give the shared
98
+ // scrolling service the content end and let each surface clamp to its own
99
+ // exact bottom coordinate.
100
+ void this.revogrid.scrollToCoordinate({ y: dimension.get('realSize') });
101
+ };
102
+ this.scheduleRowDefinitionRemap = () => {
103
+ if (this.rowDefinitionRemapQueued) {
104
+ return;
105
+ }
106
+ this.rowDefinitionRemapQueued = true;
107
+ queueMicrotask(() => {
108
+ if (!this.rowDefinitionRemapQueued) {
109
+ return;
110
+ }
111
+ this.pruneRowDefinitions();
112
+ this.reapplyRowDefinitionSizes();
113
+ this.rowDefinitionRemapQueued = false;
114
+ });
115
+ };
116
+ /** Map source-indexed row definitions back onto the current virtual order. */
117
+ this.reapplyRowDefinitionSizes = () => {
118
+ const rowDefinitions = this.providers.dimension.getRowDefinitions();
119
+ for (const rowType of rowTypes) {
120
+ const items = this.providers.data.stores[rowType].store.get('items');
121
+ const definitions = new Map(rowDefinitions
122
+ .filter(definition => definition.type === rowType)
123
+ .map(definition => [definition.index, definition.size]));
124
+ const appliedIndexes = this.appliedDefinitionIndexes.get(rowType);
125
+ if (!definitions.size && !(appliedIndexes === null || appliedIndexes === void 0 ? void 0 : appliedIndexes.size)) {
126
+ continue;
127
+ }
128
+ const dimension = this.providers.dimension.stores[rowType];
129
+ const currentSizes = dimension.store.get('sizes');
130
+ const sizes = Object.assign({}, currentSizes);
131
+ for (const index of appliedIndexes || []) {
132
+ delete sizes[index];
133
+ }
134
+ const indexes = new Set();
135
+ items.forEach((physicalIndex, virtualIndex) => {
136
+ const size = definitions.get(physicalIndex);
137
+ if (size !== undefined) {
138
+ sizes[virtualIndex] = size;
139
+ indexes.add(virtualIndex);
140
+ }
141
+ });
142
+ this.appliedDefinitionIndexes.set(rowType, indexes);
143
+ const sizeKeys = Object.keys(sizes);
144
+ if (sizeKeys.length !== Object.keys(currentSizes).length ||
145
+ sizeKeys.some(index => sizes[index] !== currentSizes[index])) {
146
+ this.providers.dimension.setCustomSizes(rowType, sizes);
147
+ }
148
+ }
149
+ };
150
+ this.config = resolveRowResizeConfig(config);
151
+ if (new.target !== RowResizePlugin) {
152
+ this.enabled = true;
153
+ this.registerEventListeners();
154
+ }
155
+ }
156
+ registerEventListeners() {
157
+ this.addEventListener('beforerowrender', this.decorateRow);
158
+ this.addEventListener('beforeanysource', () => {
159
+ this.cancel('data-change');
160
+ this.keepBottomAnchor = false;
161
+ });
162
+ this.addEventListener('afteranysource', ({ detail }) => {
163
+ this.pendingSourceCounts.set(detail.type, detail.source.length);
164
+ this.scheduleRowDefinitionRemap();
165
+ });
166
+ this.addEventListener('beforesourcesortingapply', this.cancelForDataChange);
167
+ this.addEventListener('beforesortingapply', this.cancelForDataChange);
168
+ this.addEventListener('sortingconfigchanged', this.cancelForDataChange);
169
+ this.addEventListener(BEFORE_GROUPING_APPLY_EVENT, this.cancelForDataChange);
170
+ this.addEventListener('aftersortingapply', this.scheduleRowDefinitionRemap);
171
+ this.addEventListener('beforefilterapply', this.cancelForDataChange);
172
+ this.addEventListener('afterfilterapply', this.scheduleRowDefinitionRemap);
173
+ this.addEventListener('beforerowdefinition', () => {
174
+ this.cancel('data-change');
175
+ this.scheduleRowDefinitionRemap();
176
+ });
177
+ this.addEventListener('afterthemechanged', this.scheduleRowDefinitionRemap);
178
+ this.addEventListener('aftertrimmed', this.scheduleRowDefinitionRemap);
179
+ this.addEventListener('roworderchange', this.scheduleRowDefinitionRemap);
180
+ this.addEventListener(GROUP_EXPAND_EVENT, () => {
181
+ if (this.keepBottomAnchor) {
182
+ this.pendingBottomAnchor = true;
183
+ }
184
+ this.scheduleRowDefinitionRemap();
185
+ });
186
+ this.addEventListener('aftergridrender', this.applyPendingBottomAnchor);
187
+ this.addEventListener('viewportscroll', this.updateBottomAnchorState);
188
+ this.addEventListener('rowheaderschanged', ({ detail }) => {
189
+ if (!detail && !this.config.fullRow) {
190
+ this.cancel('row-headers-hidden');
191
+ }
192
+ });
193
+ }
194
+ syncGridConfig(refresh = true) {
195
+ const { plugins = [], resizeRow } = this.revogrid;
196
+ const isCorePlugin = this.constructor === RowResizePlugin;
197
+ const hasConfiguredPlugin = plugins.some(plugin => plugin !== RowResizePlugin &&
198
+ plugin.prototype instanceof RowResizePlugin);
199
+ const enabled = !isCorePlugin ||
200
+ (!hasConfiguredPlugin && !!resizeRow);
201
+ const resizeConfig = typeof resizeRow === 'object' ? resizeRow : undefined;
202
+ const config = isCorePlugin
203
+ ? resolveRowResizeConfig(resizeConfig)
204
+ : this.config;
205
+ const configChanged = config.minHeight !== this.config.minHeight ||
206
+ config.maxHeight !== this.config.maxHeight ||
207
+ config.fullRow !== this.config.fullRow;
208
+ if (enabled === this.enabled && !configChanged) {
209
+ return;
210
+ }
211
+ this.cancel('config-change');
212
+ this.config = config;
213
+ if (enabled !== this.enabled) {
214
+ this.enabled = enabled;
215
+ if (enabled) {
216
+ this.registerEventListeners();
217
+ }
218
+ else {
219
+ this.pendingBottomAnchor = false;
220
+ this.keepBottomAnchor = false;
221
+ this.rowDefinitionRemapQueued = false;
222
+ this.pendingSourceCounts.clear();
223
+ this.clearSubscriptions();
224
+ }
225
+ }
226
+ if (refresh) {
227
+ queueMicrotask(() => void this.revogrid.refresh());
228
+ }
229
+ }
230
+ startResize(event, rowType, index) {
231
+ var _a, _b;
232
+ if (!this.enabled ||
233
+ this.active ||
234
+ event.defaultPrevented ||
235
+ !event.isPrimary ||
236
+ (event.pointerType !== 'touch' && event.button !== 0)) {
237
+ return;
238
+ }
239
+ const dimension = this.providers.dimension.stores[rowType];
240
+ const dimensionState = dimension.getCurrentState();
241
+ const viewport = this.providers.viewport.stores[rowType];
242
+ const item = getItemByIndex(dimensionState, index);
243
+ const focusedStore = this.providers.selection.focusedStore;
244
+ const selectedRowType = focusedStore
245
+ ? this.providers.selection.storesYToType[focusedStore.position.y]
246
+ : undefined;
247
+ const indexes = getRowResizeIndexes({
248
+ rowType,
249
+ rowIndex: index,
250
+ rowCount: dimensionState.count,
251
+ selectedRange: this.providers.selection.selectedRange,
252
+ selectedRowType,
253
+ });
254
+ if (!indexes.length) {
255
+ return;
256
+ }
257
+ const previousSizes = indexes.reduce((sizes, rowIndex) => {
258
+ const row = getItemByIndex(dimensionState, rowIndex);
259
+ sizes[rowIndex] = row.end - row.start;
260
+ return sizes;
261
+ }, {});
262
+ const startHeight = item.end - item.start;
263
+ const active = {
264
+ pointerId: event.pointerId,
265
+ rowType,
266
+ index,
267
+ indexes,
268
+ startY: event.clientY,
269
+ startHeight,
270
+ currentHeight: startHeight,
271
+ previousSizes,
272
+ originalCustomSizes: Object.assign({}, dimensionState.sizes),
273
+ bottomAnchored: rowType === 'rgRow' &&
274
+ this.isMainViewportAtBottom(viewport.lastCoordinate),
275
+ lastEvent: event,
276
+ };
277
+ this.active = active;
278
+ const beforeEvent = this.emit(BEFORE_ROW_RESIZE_EVENT, this.eventDetail(active, event, startHeight));
279
+ if (beforeEvent.defaultPrevented) {
280
+ if (this.active === active) {
281
+ this.active = undefined;
282
+ }
283
+ return;
284
+ }
285
+ if (!this.enabled || this.active !== active) {
286
+ return;
287
+ }
288
+ event.preventDefault();
289
+ event.stopPropagation();
290
+ const doc = this.revogrid.ownerDocument;
291
+ this.previousBodyCursor = ((_a = doc.body) === null || _a === void 0 ? void 0 : _a.style.cursor) || '';
292
+ if (doc.body) {
293
+ doc.body.style.cursor = 'row-resize';
294
+ }
295
+ doc.addEventListener('pointermove', this.onPointerMove, true);
296
+ doc.addEventListener('pointerup', this.onPointerUp, true);
297
+ doc.addEventListener('pointercancel', this.onPointerCancel, true);
298
+ doc.addEventListener('keydown', this.onKeyDown, true);
299
+ (_b = doc.defaultView) === null || _b === void 0 ? void 0 : _b.addEventListener('blur', this.onWindowBlur);
300
+ }
301
+ flushPendingResize() {
302
+ const active = this.active;
303
+ if (!active || this.pendingHeight === undefined) {
304
+ return;
305
+ }
306
+ const size = this.pendingHeight;
307
+ this.pendingHeight = undefined;
308
+ if (size === active.currentHeight) {
309
+ return;
310
+ }
311
+ this.providers.dimension.setCustomSizes(active.rowType, createRowResizePatch(active.indexes, size), true);
312
+ this.requestBottomAnchor(active);
313
+ active.currentHeight = size;
314
+ this.emit(ROW_RESIZE_EVENT, this.eventDetail(active, active.lastEvent, size));
315
+ }
316
+ cancel(reason) {
317
+ const active = this.active;
318
+ if (!active) {
319
+ return;
320
+ }
321
+ const currentSizes = Object.assign({}, this.providers.dimension.stores[active.rowType].store.get('sizes'));
322
+ for (const index of active.indexes) {
323
+ if (Object.hasOwn(active.originalCustomSizes, index)) {
324
+ currentSizes[index] = active.originalCustomSizes[index];
325
+ }
326
+ else {
327
+ delete currentSizes[index];
328
+ }
329
+ }
330
+ this.providers.dimension.setCustomSizes(active.rowType, currentSizes);
331
+ this.requestBottomAnchor(active);
332
+ const detail = Object.assign(Object.assign({}, this.eventDetail(active, active.lastEvent, active.startHeight)), { reason });
333
+ this.finishGesture();
334
+ this.emit(ROW_RESIZE_CANCEL_EVENT, detail);
335
+ }
336
+ eventDetail(active, originalEvent, size) {
337
+ return {
338
+ rowType: active.rowType,
339
+ index: active.index,
340
+ indexes: [...active.indexes],
341
+ size,
342
+ previousSizes: Object.assign({}, active.previousSizes),
343
+ originalEvent,
344
+ };
345
+ }
346
+ commitResize(active) {
347
+ if (active.currentHeight === active.startHeight) {
348
+ return;
349
+ }
350
+ const items = this.providers.data.stores[active.rowType].store.get('items');
351
+ const physicalIndexes = active.indexes.reduce((result, index) => {
352
+ const physicalIndex = items[index];
353
+ if (physicalIndex !== undefined) {
354
+ result.push(physicalIndex);
355
+ }
356
+ return result;
357
+ }, []);
358
+ if (physicalIndexes.length) {
359
+ const rowDefinitions = mergeRowResizeDefinitions(this.providers.dimension.getRowDefinitions(), active.rowType, physicalIndexes, active.currentHeight);
360
+ this.providers.dimension.setRowDefinitions(rowDefinitions);
361
+ this.scheduleRowDefinitionRemap();
362
+ this.keepBottomAnchor = active.bottomAnchored;
363
+ this.requestBottomAnchor(active);
364
+ }
365
+ }
366
+ requestBottomAnchor(active) {
367
+ if (active.bottomAnchored) {
368
+ this.pendingBottomAnchor = true;
369
+ }
370
+ }
371
+ isMainViewportAtBottom(coordinate) {
372
+ const dimension = this.providers.dimension.stores.rgRow.getCurrentState();
373
+ const viewport = this.providers.viewport.stores.rgRow.store.state;
374
+ return (dimension.realSize > viewport.clientSize &&
375
+ coordinate >= getViewportMaxCoordinate(dimension, viewport.virtualSize));
376
+ }
377
+ pruneRowDefinitions() {
378
+ if (!this.pendingSourceCounts.size) {
379
+ return;
380
+ }
381
+ const definitions = this.providers.dimension.getRowDefinitions();
382
+ const rowDefinitions = definitions.filter(definition => {
383
+ const count = this.pendingSourceCounts.get(definition.type);
384
+ return count === undefined || definition.index < count;
385
+ });
386
+ this.pendingSourceCounts.clear();
387
+ if (rowDefinitions.length !== definitions.length) {
388
+ this.providers.dimension.setRowDefinitions(rowDefinitions);
389
+ }
390
+ }
391
+ finishGesture() {
392
+ const doc = this.revogrid.ownerDocument;
393
+ const view = doc.defaultView;
394
+ if (this.animationFrame !== undefined) {
395
+ view === null || view === void 0 ? void 0 : view.cancelAnimationFrame(this.animationFrame);
396
+ }
397
+ doc.removeEventListener('pointermove', this.onPointerMove, true);
398
+ doc.removeEventListener('pointerup', this.onPointerUp, true);
399
+ doc.removeEventListener('pointercancel', this.onPointerCancel, true);
400
+ doc.removeEventListener('keydown', this.onKeyDown, true);
401
+ view === null || view === void 0 ? void 0 : view.removeEventListener('blur', this.onWindowBlur);
402
+ if (doc.body) {
403
+ doc.body.style.cursor = this.previousBodyCursor;
404
+ }
405
+ this.animationFrame = undefined;
406
+ this.pendingHeight = undefined;
407
+ this.active = undefined;
408
+ }
409
+ destroy() {
410
+ this.cancel('destroy');
411
+ this.keepBottomAnchor = false;
412
+ this.rowDefinitionRemapQueued = false;
413
+ this.pendingSourceCounts.clear();
414
+ super.destroy();
415
+ }
416
+ }
@@ -0,0 +1,55 @@
1
+ /*!
2
+ * Built by Revolist OU ❤️
3
+ */
4
+ export const DEFAULT_MIN_ROW_HEIGHT = 20;
5
+ const finiteNumber = (value) => typeof value === 'number' && Number.isFinite(value);
6
+ export function resolveRowResizeConfig(config = {}) {
7
+ const minHeight = finiteNumber(config.minHeight)
8
+ ? Math.max(1, Math.round(config.minHeight))
9
+ : DEFAULT_MIN_ROW_HEIGHT;
10
+ const maxHeight = finiteNumber(config.maxHeight)
11
+ ? Math.max(minHeight, Math.round(config.maxHeight))
12
+ : undefined;
13
+ return { minHeight, maxHeight, fullRow: config.fullRow === true };
14
+ }
15
+ export function clampRowResizeHeight(height, config) {
16
+ var _a;
17
+ const rounded = Number.isFinite(height)
18
+ ? Math.round(height)
19
+ : config.minHeight;
20
+ return Math.min(Math.max(rounded, config.minHeight), (_a = config.maxHeight) !== null && _a !== void 0 ? _a : Number.POSITIVE_INFINITY);
21
+ }
22
+ export function getRowResizeIndexes({ rowType, rowIndex, rowCount, selectedRange, selectedRowType, }) {
23
+ if (!selectedRange ||
24
+ selectedRowType !== rowType ||
25
+ rowIndex < Math.min(selectedRange.y, selectedRange.y1) ||
26
+ rowIndex > Math.max(selectedRange.y, selectedRange.y1)) {
27
+ return rowIndex >= 0 && rowIndex < rowCount ? [rowIndex] : [];
28
+ }
29
+ const start = Math.max(0, Math.min(selectedRange.y, selectedRange.y1));
30
+ const end = Math.min(rowCount - 1, Math.max(selectedRange.y, selectedRange.y1));
31
+ return Array.from({ length: Math.max(0, end - start + 1) }, (_, i) => start + i);
32
+ }
33
+ export function createRowResizePatch(indexes, size) {
34
+ return indexes.reduce((patch, index) => {
35
+ patch[index] = size;
36
+ return patch;
37
+ }, {});
38
+ }
39
+ export function mergeRowResizeDefinitions(definitions, rowType, physicalIndexes, size) {
40
+ const targetIndexes = new Set(physicalIndexes);
41
+ const existingIndexes = new Set();
42
+ const merged = definitions.map(definition => {
43
+ if (definition.type !== rowType || !targetIndexes.has(definition.index)) {
44
+ return definition;
45
+ }
46
+ existingIndexes.add(definition.index);
47
+ return Object.assign(Object.assign({}, definition), { size });
48
+ });
49
+ for (const index of targetIndexes) {
50
+ if (!existingIndexes.has(index)) {
51
+ merged.push({ type: rowType, index, size });
52
+ }
53
+ }
54
+ return merged;
55
+ }
@@ -6,6 +6,7 @@ import { BasePlugin } from "../base.plugin";
6
6
  import { getColumnByProp } from "../../utils/column.utils";
7
7
  import { columnTypes, rowTypes } from "../../store/index";
8
8
  import { isGrouping } from "../groupingRow/grouping.service";
9
+ import { gatherGroupedRowIndexes } from "../groupingRow/grouping.sorting.service";
9
10
  import { getComparer, getNextOrder, getSortingIndex, hasActiveSorting, sortIndexByItems, } from "./sorting.func";
10
11
  export * from './sorting.types';
11
12
  export * from './sorting.func';
@@ -13,18 +14,6 @@ export * from './sorting.sign';
13
14
  function getSortableRowIndexes(indexes, source) {
14
15
  return indexes.filter(index => !isGrouping(source[index]));
15
16
  }
16
- function mergeSortedRowsWithGroups(indexes, source, sortedRows) {
17
- if (sortedRows.length === indexes.length) {
18
- return sortedRows;
19
- }
20
- let rowIndex = 0;
21
- return indexes.map(index => {
22
- if (isGrouping(source[index])) {
23
- return index;
24
- }
25
- return sortedRows[rowIndex++];
26
- });
27
- }
28
17
  /**
29
18
  * Lifecycle
30
19
  * 1. @event `beforesorting` - Triggered when sorting just starts. Nothing has happened yet. This can be triggered from a column or from the source. If the type is from rows, the column will be undefined.
@@ -184,6 +173,7 @@ export class SortingPlugin extends BasePlugin {
184
173
  storeService.setData({ proxyItems: newItemsOrder });
185
174
  }
186
175
  applySortingForStore(type, sorting, sortingFunc, sortingColumns, sortingOrder, ignoreViewportUpdate) {
176
+ var _a;
187
177
  const storeService = this.providers.data.stores[type];
188
178
  // row data
189
179
  const source = storeService.store.get('source');
@@ -191,7 +181,10 @@ export class SortingPlugin extends BasePlugin {
191
181
  const proxyItems = storeService.store.get('proxyItems');
192
182
  const sortItems = getSortableRowIndexes(proxyItems, source);
193
183
  const sortedItems = sortIndexByItems([...sortItems], source, sortingFunc, sorting, sortingColumns, sortingOrder);
194
- const newItemsOrder = mergeSortedRowsWithGroups(proxyItems, source, sortedItems);
184
+ const hasGroupingRows = sortedItems.length !== proxyItems.length;
185
+ const newItemsOrder = hasGroupingRows
186
+ ? (_a = gatherGroupedRowIndexes(source, sortedItems)) !== null && _a !== void 0 ? _a : proxyItems
187
+ : sortedItems;
195
188
  // take row indexes before trim applied and proxy items
196
189
  const prevItems = storeService.store.get('items');
197
190
  storeService.setData({
@@ -217,6 +210,16 @@ export class SortingPlugin extends BasePlugin {
217
210
  }
218
211
  this.postponeSort(order, sortingFunc, sortingColumns, sortingOrder, ignoreViewportUpdate);
219
212
  }
213
+ /**
214
+ * Schedules the current active sort again after another plugin rebuilds row
215
+ * proxy indexes while keeping the physical source unchanged.
216
+ */
217
+ reapplySorting() {
218
+ if (!hasActiveSorting(this.sorting) || !this.sortingFunc) {
219
+ return;
220
+ }
221
+ this.startSorting(this.sorting, this.sortingFunc, this.sortingColumns, this.sortingOrder);
222
+ }
220
223
  /**
221
224
  * Applies sorting requested by a sortable header click.
222
225
  *
@@ -2,6 +2,7 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  import { BasePlugin } from "../base.plugin";
5
+ const toAriaIndex = (index) => `${index + 1}`;
5
6
  /**
6
7
  * WCAG Plugin is responsible for enhancing the accessibility features of the RevoGrid component.
7
8
  * It ensures that the grid is fully compliant with Web Content Accessibility Guidelines (WCAG) 2.1.
@@ -45,14 +46,14 @@ export class WCAGPlugin extends BasePlugin {
45
46
  column.columnProperties = (...args) => {
46
47
  const result = (columnProperties === null || columnProperties === void 0 ? void 0 : columnProperties(...args)) || {};
47
48
  result.role = 'columnheader';
48
- result['aria-colindex'] = `${index}`;
49
+ result['aria-colindex'] = toAriaIndex(index);
49
50
  return result;
50
51
  };
51
52
  column.cellProperties = (...args) => {
52
53
  const wcagProps = {
53
54
  ['role']: 'gridcell',
54
- ['aria-colindex']: `${index}`,
55
- ['aria-rowindex']: `${args[0].rowIndex}`,
55
+ ['aria-colindex']: toAriaIndex(index),
56
+ ['aria-rowindex']: toAriaIndex(args[0].rowIndex),
56
57
  ['tabindex']: -1,
57
58
  };
58
59
  const columnProps = (cellProperties === null || cellProperties === void 0 ? void 0 : cellProperties(...args)) || {};
@@ -67,7 +68,7 @@ export class WCAGPlugin extends BasePlugin {
67
68
  revogrid.setAttribute('aria-rowcount', `${detail.source.length}`);
68
69
  });
69
70
  this.addEventListener('beforerowrender', ({ detail, }) => {
70
- detail.node.$attrs$ = Object.assign(Object.assign({}, detail.node.$attrs$), { role: 'row', ['aria-rowindex']: detail.item.itemIndex });
71
+ detail.node.$attrs$ = Object.assign(Object.assign({}, detail.node.$attrs$), { role: 'row', ['aria-rowindex']: toAriaIndex(detail.item.itemIndex) });
71
72
  });
72
73
  // focuscell
73
74
  this.addEventListener('afterfocus', async (e) => {
@@ -436,7 +436,7 @@ function onLoad() {
436
436
  grid.range = true;
437
437
  grid.useClipboard = { rangeFill: true };
438
438
  grid.resize = true;
439
- grid.filter = true;
439
+ grid.resizeRow = { fullRow: true };
440
440
 
441
441
  grid.exporting = true;
442
442
  grid.rowHeaders = true;
@@ -2,7 +2,7 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  import reduce from "lodash/reduce";
5
- import { isRowType, rowTypes, DataStore, getSourceItem, getVisibleSourceItem, } from "../store/index";
5
+ import { isRowType, rowTypes, DataStore, getSourceItem, } from "../store/index";
6
6
  /**
7
7
  * Data source provider
8
8
  *
@@ -105,7 +105,13 @@ export class DataProvider {
105
105
  store.addTrimmed(trimmed);
106
106
  this.dimensionProvider.setTrimmed(trimmed, type);
107
107
  if (type === 'rgRow') {
108
- this.dimensionProvider.setData(getVisibleSourceItem(store.store).length, type);
108
+ this.dimensionProvider.setData(store.store.get('items').length, type);
109
109
  }
110
110
  }
111
+ /** Keep a row source empty until its current asynchronous update is ready. */
112
+ setItemsPending(pending, type = 'rgRow') {
113
+ const store = this.stores[type];
114
+ store.setItemsPending(pending);
115
+ this.dimensionProvider.setData(store.store.get('items').length, type, type !== 'rgRow');
116
+ }
111
117
  }
@@ -19,7 +19,9 @@ export function isVirtualXDimension(type, disableVirtualX = false, virtualX = DE
19
19
  export default class DimensionProvider {
20
20
  constructor(viewports, config) {
21
21
  this.viewports = viewports;
22
- const sizeChanged = debounce((k) => config.realSizeChanged(k), RESIZE_INTERVAL);
22
+ this.config = config;
23
+ this.rowDefinitions = [];
24
+ const sizeChanged = debounce((k) => this.config.realSizeChanged(k), RESIZE_INTERVAL);
23
25
  this.stores = [...rowTypes, ...columnTypes].reduce((sources, t) => {
24
26
  sources[t] = new DimensionStore(t);
25
27
  sources[t].store.onChange('realSize', () => sizeChanged(t));
@@ -37,6 +39,20 @@ export default class DimensionProvider {
37
39
  this.viewports.stores[t].setOriginalSizes(this.stores[t].store.get('originItemSize'));
38
40
  this.setItemCount(count, t);
39
41
  }
42
+ getRowDefinitions() {
43
+ return this.rowDefinitions;
44
+ }
45
+ syncRowDefinitions(definitions) {
46
+ this.rowDefinitions = definitions;
47
+ }
48
+ setRowDefinitions(definitions) {
49
+ var _a, _b;
50
+ if (definitions === this.rowDefinitions) {
51
+ return;
52
+ }
53
+ this.syncRowDefinitions(definitions);
54
+ (_b = (_a = this.config).rowDefinitionsChanged) === null || _b === void 0 ? void 0 : _b.call(_a, definitions);
55
+ }
40
56
  /**
41
57
  * Apply new custom sizes to dimension and view port
42
58
  * @param type - dimension type
@@ -37,7 +37,7 @@ export class LocalScrollTimer {
37
37
  * Remember last mw event time
38
38
  */
39
39
  latestScrollUpdate(dimension) {
40
- this.mouseWheelScrollTimestamp[dimension] = new Date().getTime();
40
+ this.mouseWheelScrollTimestamp[dimension] = Date.now();
41
41
  }
42
42
  isReady(type, coordinate) {
43
43
  // if there is a callback, clear it
@@ -48,7 +48,7 @@ export class LocalScrollTimer {
48
48
  return this.verifyChange(type, coordinate);
49
49
  }
50
50
  verifyChange(type, coordinate) {
51
- const now = new Date().getTime();
51
+ const now = Date.now();
52
52
  const change = now - this.mouseWheelScrollTimestamp[type];
53
53
  return change > this.scrollThrottling &&
54
54
  coordinate !== this.lastKnownScrollCoordinate[type];
@@ -66,7 +66,7 @@ export class LocalScrollTimer {
66
66
  // save lastScrollUpdate callback
67
67
  const callback = this.lastScrollUpdateCallbacks[type] = {
68
68
  callback: lastScrollUpdate,
69
- timestamp: new Date().getTime(),
69
+ timestamp: Date.now(),
70
70
  coordinate,
71
71
  timeout: 0,
72
72
  };