@revolist/revogrid 4.22.1 → 4.23.0

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 (120) hide show
  1. package/dist/cjs/{cell-renderer-BQdEGQXP.js → cell-renderer-DWJ9Px9f.js} +9 -3
  2. package/dist/cjs/{column.drag.plugin-RDjQhKCH.js → column.drag.plugin-CaEBDG-Q.js} +391 -256
  3. package/dist/cjs/{column.service-DXYMehqK.js → column.service-f612L4ql.js} +1 -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-4yq9_WbM.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 +35 -15
  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 +26 -17
  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 +5 -2
  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 +6 -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/moveColumn/column.drag.plugin.js +4 -4
  34. package/dist/collection/plugins/sorting/sorting.func.js +173 -15
  35. package/dist/collection/plugins/sorting/sorting.plugin.js +167 -84
  36. package/dist/collection/plugins/sorting/sorting.sign.js +7 -1
  37. package/dist/collection/serve/controller.js +98 -37
  38. package/dist/collection/serve/data.js +273 -144
  39. package/dist/collection/services/dimension.provider.js +16 -1
  40. package/dist/collection/services/local.scroll.service.js +59 -24
  41. package/dist/collection/services/scroll.dimension.helpers.js +83 -0
  42. package/dist/collection/services/selection.store.connector.js +4 -1
  43. package/dist/collection/store/dimension/dimension.recalculate.plugin.js +22 -9
  44. package/dist/collection/store/dimension/dimension.store.js +4 -2
  45. package/dist/collection/store/vp/viewport.helpers.js +9 -0
  46. package/dist/collection/store/vp/viewport.store.js +5 -16
  47. package/dist/collection/utils/store.utils.js +3 -3
  48. package/dist/{revo-grid/cell-renderer-CALsEsnh.js → esm/cell-renderer-8UiGd-s7.js} +9 -3
  49. package/dist/esm/{column.drag.plugin-Dy5ztusn.js → column.drag.plugin-BsfhsfmB.js} +388 -255
  50. package/dist/esm/{column.service-CCvAi5l4.js → column.service-DbpulTog.js} +1 -1
  51. package/dist/{revo-grid/debounce-BfO9dz9v.js → esm/debounce-PCRWZliA.js} +1 -1
  52. package/dist/{revo-grid/dimension.helpers-DmIvjIa7.js → esm/dimension.helpers-CGKwSvw6.js} +7 -128
  53. package/dist/esm/{edit.utils-DYN6XZh8.js → edit.utils-Dnnbd0xG.js} +1 -1
  54. package/dist/{revo-grid/header-cell-renderer-DU8wKAbg.js → esm/header-cell-renderer-DGI2FAD8.js} +1 -1
  55. package/dist/esm/index-Db3qZoW5.js +127 -0
  56. package/dist/esm/index.js +11 -10
  57. package/dist/esm/revo-grid.entry.js +34 -14
  58. package/dist/esm/revogr-attribution_7.entry.js +42 -24
  59. package/dist/esm/revogr-clipboard_3.entry.js +11 -9
  60. package/dist/esm/revogr-data_4.entry.js +27 -18
  61. package/dist/esm/revogr-filter-panel.entry.js +3 -2
  62. package/dist/esm/{text-editor-DpCnd6Fq.js → text-editor-C3RUSwH5.js} +2 -2
  63. package/dist/esm/{throttle-ERvyruXb.js → throttle-CaUDyxyU.js} +60 -25
  64. package/dist/esm/viewport.helpers-CoCAvmZs.js +133 -0
  65. package/dist/{revo-grid/viewport.store-CFjDW-3l.js → esm/viewport.store-COAfzAyu.js} +15 -17
  66. package/dist/{esm/cell-renderer-CALsEsnh.js → revo-grid/cell-renderer-8UiGd-s7.js} +9 -3
  67. package/dist/revo-grid/{column.drag.plugin-Dy5ztusn.js → column.drag.plugin-BsfhsfmB.js} +388 -255
  68. package/dist/revo-grid/{column.service-CCvAi5l4.js → column.service-DbpulTog.js} +1 -1
  69. package/dist/{esm/debounce-BfO9dz9v.js → revo-grid/debounce-PCRWZliA.js} +1 -1
  70. package/dist/{esm/dimension.helpers-DmIvjIa7.js → revo-grid/dimension.helpers-CGKwSvw6.js} +7 -128
  71. package/dist/revo-grid/{edit.utils-DYN6XZh8.js → edit.utils-Dnnbd0xG.js} +1 -1
  72. package/dist/{esm/header-cell-renderer-DU8wKAbg.js → revo-grid/header-cell-renderer-DGI2FAD8.js} +1 -1
  73. package/dist/revo-grid/index-Db3qZoW5.js +127 -0
  74. package/dist/revo-grid/index.esm.js +11 -10
  75. package/dist/revo-grid/revo-grid.entry.js +34 -14
  76. package/dist/revo-grid/revogr-attribution_7.entry.js +42 -24
  77. package/dist/revo-grid/revogr-clipboard_3.entry.js +11 -9
  78. package/dist/revo-grid/revogr-data_4.entry.js +27 -18
  79. package/dist/revo-grid/revogr-filter-panel.entry.js +3 -2
  80. package/dist/revo-grid/{text-editor-DpCnd6Fq.js → text-editor-C3RUSwH5.js} +2 -2
  81. package/dist/revo-grid/{throttle-ERvyruXb.js → throttle-CaUDyxyU.js} +60 -25
  82. package/dist/revo-grid/viewport.helpers-CoCAvmZs.js +133 -0
  83. package/dist/{esm/viewport.store-CFjDW-3l.js → revo-grid/viewport.store-COAfzAyu.js} +15 -17
  84. package/dist/types/components/header/header-group-renderer.d.ts +1 -0
  85. package/dist/types/components/header/header-renderer.d.ts +1 -0
  86. package/dist/types/components/overlay/keyboard.service.d.ts +5 -0
  87. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +8 -0
  88. package/dist/types/plugins/sorting/sorting.func.d.ts +25 -2
  89. package/dist/types/plugins/sorting/sorting.plugin.d.ts +84 -9
  90. package/dist/types/plugins/sorting/sorting.sign.d.ts +5 -1
  91. package/dist/types/plugins/sorting/sorting.types.d.ts +46 -1
  92. package/dist/types/services/local.scroll.service.d.ts +10 -2
  93. package/dist/types/services/scroll.dimension.helpers.d.ts +20 -0
  94. package/dist/types/store/vp/viewport.helpers.d.ts +2 -0
  95. package/dist/types/types/interfaces.d.ts +11 -0
  96. package/hydrate/index.js +649 -365
  97. package/hydrate/index.mjs +649 -365
  98. package/package.json +1 -1
  99. package/standalone/column.service.js +1 -1
  100. package/standalone/data.store.js +1 -1
  101. package/standalone/debounce.js +1 -1
  102. package/standalone/dimension.helpers.js +1 -1
  103. package/standalone/index.js +1 -1
  104. package/standalone/local.scroll.timer.js +1 -1
  105. package/standalone/revo-grid.js +1 -1
  106. package/standalone/revogr-data2.js +1 -1
  107. package/standalone/revogr-filter-panel.js +1 -1
  108. package/standalone/revogr-header2.js +1 -1
  109. package/standalone/revogr-order-editor2.js +1 -1
  110. package/standalone/revogr-overlay-selection2.js +1 -1
  111. package/standalone/revogr-row-headers.js +1 -1
  112. package/standalone/revogr-row-headers2.js +1 -1
  113. package/standalone/revogr-scroll-virtual2.js +1 -1
  114. package/standalone/revogr-viewport-scroll2.js +1 -1
  115. package/standalone/selection.utils.js +1 -1
  116. package/standalone/throttle.js +1 -1
  117. package/standalone/toNumber.js +1 -1
  118. package/dist/cjs/viewport.helpers-BAovztDd.js +0 -58
  119. package/dist/esm/viewport.helpers-VXhsJZtn.js +0 -52
  120. package/dist/revo-grid/viewport.helpers-VXhsJZtn.js +0 -52
@@ -22,6 +22,8 @@ function naturalSort(prop, a, b) {
22
22
  return aValue.localeCompare(bValue, 'en', { numeric: true });
23
23
  }
24
24
 
25
+ const DEFAULT_MAX_CELLS_PER_CHUNK = 50_000;
26
+
25
27
  const DEFAULT_CONFIG = {
26
28
  topPinned: [],
27
29
  groupedHeader: false,
@@ -34,168 +36,295 @@ const DEFAULT_CONFIG = {
34
36
  order: undefined,
35
37
  };
36
38
 
39
+ function getConfig(config = {}) {
40
+ return {
41
+ ...DEFAULT_CONFIG,
42
+ ...config,
43
+ };
44
+ }
45
+
46
+ function createColumn(rgCol, {
47
+ colPinStart,
48
+ colPinEnd,
49
+ rowDrag,
50
+ order,
51
+ }) {
52
+ const column = {
53
+ name: generateHeader(rgCol),
54
+ prop: rgCol,
55
+ sortable: true,
56
+ size: 100,
57
+ // custom sorting except of 0 row
58
+ cellCompare: !!rgCol && rgCol % 2 == 0 ? naturalSort : undefined,
59
+ cellProperties: ({ colIndex }) => ({
60
+ className: {
61
+ 'first-column': colIndex === 0,
62
+ },
63
+ class: {
64
+ 'first-column-class': colIndex === 0,
65
+ },
66
+ }),
67
+
68
+ // custom filter
69
+ // filter: 'myFilterType',
70
+ };
71
+
72
+ if (colPinStart.includes(rgCol)) {
73
+ column.pin = 'colPinStart';
74
+ }
75
+ if (colPinEnd.includes(rgCol)) {
76
+ column.pin = 'colPinEnd';
77
+ }
78
+ if (!rgCol) {
79
+ column.sortable = true;
80
+ column.cellProperties = ({ rowIndex }) => {
81
+ return {
82
+ 'custom-row-index': rowIndex,
83
+ };
84
+ };
85
+ column.rowDrag = true;
86
+ }
87
+ if (rgCol === rowDrag) {
88
+ column.rowDrag = true;
89
+ }
90
+ if (rgCol === order) {
91
+ column.order = 'desc';
92
+ }
93
+
94
+ return column;
95
+ }
96
+
97
+ function createColumns(config) {
98
+ const columns = [];
99
+ for (let rgCol = 0; rgCol < config.cols; rgCol++) {
100
+ columns.push(createColumn(rgCol, config));
101
+ }
102
+ return columns;
103
+ }
104
+
105
+ function createRow(rgRow, cols) {
106
+ const row = {};
107
+
108
+ if (rgRow === 2) {
109
+ // highlighted
110
+ row['row-style'] = 'highlighted-row';
111
+ }
112
+
113
+ // apply different key for grouping
114
+ if (rgRow % 2) {
115
+ row.key = 'a';
116
+ } else {
117
+ row.key = 'b';
118
+ }
119
+ if (rgRow % 4) {
120
+ row.key2 = 'c';
121
+ } else if (rgRow % 3) {
122
+ row.key2 = 'd';
123
+ }
124
+
125
+ for (let rgCol = 0; rgCol < cols; rgCol++) {
126
+ row[rgCol] = `${rgRow}:${rgCol}`;
127
+ }
128
+
129
+ return row;
130
+ }
131
+
132
+ function applyGroupedHeaders(headers, groupedHeader) {
133
+ if (!groupedHeader || headers.length <= 2) {
134
+ return;
135
+ }
136
+
137
+ const grouped = headers.splice(1, Math.min(headers.length - 1, 30));
138
+ const grouped2 = grouped.splice(0, Math.min(headers.length - 1, 2));
139
+ grouped2.length && grouped.push({
140
+ name: 'Grouped2',
141
+ children: grouped2,
142
+ columnTemplate: (h, { value }) => {
143
+ return h('div', {
144
+ class: 'grouped-header',
145
+ }, 'Grouped2');
146
+ },
147
+ });
148
+ grouped.length && headers.splice(
149
+ 6,
150
+ 0,
151
+ ...[
152
+ {
153
+ name: 'Grouped',
154
+ children: grouped,
155
+ },
156
+ ],
157
+ );
158
+ const grouped4 = headers.splice(0, Math.min(headers.length - 1, 4));
159
+ grouped4.length && headers.splice(
160
+ 0,
161
+ 0,
162
+ ...[
163
+ {
164
+ name: 'Grouped3',
165
+ children: grouped4,
166
+ },
167
+ ],
168
+ );
169
+ }
170
+
171
+ function getPinnedSets(topPinned, bottomPinned) {
172
+ return {
173
+ topPinnedSet: new Set(topPinned),
174
+ bottomPinnedSet: new Set(bottomPinned),
175
+ };
176
+ }
177
+
178
+ function addRow({
179
+ row,
180
+ rgRow,
181
+ result,
182
+ pinnedTopRows,
183
+ pinnedBottomRows,
184
+ topPinnedSet,
185
+ bottomPinnedSet,
186
+ }) {
187
+ if (topPinnedSet.has(rgRow)) {
188
+ pinnedTopRows.push({ ...row });
189
+ return;
190
+ }
191
+ if (bottomPinnedSet.has(rgRow)) {
192
+ pinnedBottomRows.push({ ...row });
193
+ return;
194
+ }
195
+ result.push(row);
196
+ }
197
+
198
+ function finishData({ result, pinnedTopRows, pinnedBottomRows, headers, groupedHeader }) {
199
+ applyGroupedHeaders(headers, groupedHeader);
200
+ return {
201
+ rows: result,
202
+ pinnedTopRows,
203
+ pinnedBottomRows,
204
+ headers,
205
+ };
206
+ }
207
+
208
+ function isCanceled(isCanceledFn) {
209
+ return typeof isCanceledFn === 'function' && isCanceledFn();
210
+ }
211
+
212
+ function yieldToBrowser() {
213
+ return new Promise(resolve => {
214
+ if (typeof requestIdleCallback === 'function') {
215
+ requestIdleCallback(() => resolve(), { timeout: 50 });
216
+ return;
217
+ }
218
+ setTimeout(resolve, 0);
219
+ });
220
+ }
221
+
222
+ function getChunkRows(cols, maxCellsPerChunk) {
223
+ if (!cols) {
224
+ return maxCellsPerChunk;
225
+ }
226
+ return Math.max(1, Math.floor(maxCellsPerChunk / cols));
227
+ }
228
+
37
229
  export function generateFakeDataObject(config = {}) {
38
230
  const {
39
231
  topPinned,
40
232
  bottomPinned,
41
- colPinStart,
42
- colPinEnd,
43
233
  groupedHeader,
44
234
 
45
- rowDrag,
46
235
  rows,
47
236
  cols,
48
- order,
49
- } = {
50
- ...DEFAULT_CONFIG,
51
- ...config,
52
- };
237
+ } = getConfig(config);
53
238
 
54
- let result = [];
55
- const columns = {};
56
- // all cells
57
- const all = cols * rows;
58
- for (let j = 0; j < all; j++) {
59
- let rgCol = j % cols;
60
- let rgRow = (j / cols) | 0;
61
- if (!result[rgRow]) {
62
- result[rgRow] = {};
63
-
64
- if (rgRow === 2) {
65
- // highlighted
66
- result[rgRow]['row-style'] = 'highlighted-row';
67
- }
68
-
69
- // apply different key for grouping
70
- if (rgRow % 2) {
71
- result[rgRow].key = 'a';
72
- } else {
73
- result[rgRow].key = 'b';
74
- }
75
- if (rgRow % 4) {
76
- result[rgRow].key2 = 'c';
77
- } else if (rgRow % 3) {
78
- result[rgRow].key2 = 'd';
79
- }
80
- }
81
- if (!columns[rgCol]) {
82
- columns[rgCol] = {
83
- name: generateHeader(rgCol),
84
- prop: rgCol,
85
- sortable: true,
86
- size: 100,
87
- // custom sorting except of 0 row
88
- cellCompare: !!rgCol && rgCol % 2 == 0 ? naturalSort : undefined,
89
- cellProperties: ({ colIndex }) => ({
90
- className: {
91
- 'first-column': colIndex === 0,
92
- },
93
- class: {
94
- 'first-column-class': colIndex === 0,
95
- }
96
- })
97
-
98
- // custom filter
99
- // filter: 'myFilterType',
100
- };
239
+ const result = [];
240
+ const headers = createColumns(getConfig(config));
241
+ const pinnedTopRows = [];
242
+ const pinnedBottomRows = [];
243
+ const { topPinnedSet, bottomPinnedSet } = getPinnedSets(topPinned, bottomPinned);
101
244
 
102
- // apply config
103
- if (colPinStart.indexOf(j) > -1) {
104
- columns[rgCol].pin = 'colPinStart';
105
- }
106
- // apply config
107
- if (colPinEnd.indexOf(j) > -1) {
108
- columns[rgCol].pin = 'colPinEnd';
109
- }
110
- if (!rgCol) {
111
- columns[rgCol].order = 'desc';
112
- columns[rgCol].sortable = true;
113
- }
114
- }
115
- result[rgRow][rgCol] = `${rgRow}:${rgCol}`; // rgRow % 5 ? rgCol : rgRow % 3 ? (rgCol % 3 ? 2 : 3) : rgRow; // rgRow + ':' + rgCol;
116
-
117
- if (rgCol === 0) {
118
- columns[rgCol].cellProperties = ({ rowIndex }) => {
119
- return {
120
- 'custom-row-index': rowIndex
121
- };
122
- }
123
-
124
- columns[rgCol].rowDrag = true;
125
-
126
- // columns[rgCol].cellParser = () => 'a';
127
- // columns[rgCol].cellTemplate = (h, { value }) => {
128
- // // delay
129
- // for(let i = 0; i < 10000000; i++) {
130
- // // do nothing, this is just to slow down to test performance
131
- // }
132
- // return value;
133
- // }
134
- }
135
- // apply config
136
- if (rgCol === rowDrag) {
137
- columns[rgCol].rowDrag = true;
138
- }
139
- // apply config
140
- if (rgCol === order) {
141
- columns[rgCol].order = 'desc';
142
- }
245
+ for (let rgRow = 0; rgRow < rows; rgRow++) {
246
+ addRow({
247
+ row: createRow(rgRow, cols),
248
+ rgRow,
249
+ result,
250
+ pinnedTopRows,
251
+ pinnedBottomRows,
252
+ topPinnedSet,
253
+ bottomPinnedSet,
254
+ });
143
255
  }
256
+
257
+ return finishData({
258
+ result,
259
+ pinnedTopRows,
260
+ pinnedBottomRows,
261
+ headers,
262
+ groupedHeader,
263
+ });
264
+ }
265
+
266
+ export async function generateFakeDataObjectAsync(config = {}, options = {}) {
267
+ const dataConfig = getConfig(config);
268
+ const {
269
+ rows,
270
+ cols,
271
+ topPinned,
272
+ bottomPinned,
273
+ groupedHeader,
274
+ } = dataConfig;
275
+ const {
276
+ maxCellsPerChunk = DEFAULT_MAX_CELLS_PER_CHUNK,
277
+ onProgress,
278
+ isCanceled: isCanceledFn,
279
+ } = options;
280
+
281
+ const result = [];
144
282
  const pinnedTopRows = [];
145
283
  const pinnedBottomRows = [];
146
- if (topPinned?.length || bottomPinned?.length) {
147
- result = result.filter((row, i) => {
148
- if (topPinned.indexOf(i) > -1) {
149
- pinnedTopRows.push({ ...row });
150
- return false;
151
- }
152
- if (bottomPinned.indexOf(i) > -1) {
153
- pinnedBottomRows.push({ ...row });
154
- return false;
155
- }
156
- return true;
284
+ const headers = createColumns(dataConfig);
285
+ const { topPinnedSet, bottomPinnedSet } = getPinnedSets(topPinned, bottomPinned);
286
+ const chunkRows = getChunkRows(cols, maxCellsPerChunk);
287
+
288
+ for (let rgRow = 0; rgRow < rows; rgRow++) {
289
+ if (isCanceled(isCanceledFn)) {
290
+ return null;
291
+ }
292
+
293
+ addRow({
294
+ row: createRow(rgRow, cols),
295
+ rgRow,
296
+ result,
297
+ pinnedTopRows,
298
+ pinnedBottomRows,
299
+ topPinnedSet,
300
+ bottomPinnedSet,
157
301
  });
302
+
303
+ if ((rgRow + 1) % chunkRows === 0) {
304
+ onProgress?.({
305
+ rows: rgRow + 1,
306
+ totalRows: rows,
307
+ });
308
+ await yieldToBrowser();
309
+ }
158
310
  }
159
- let headers = Object.keys(columns).map(k => columns[k]);
160
-
161
- if (groupedHeader && headers.length > 2) {
162
- const grouped = headers.splice(1, Math.min(headers.length - 1, 30));
163
- const grouped2 = grouped.splice(0, Math.min(headers.length - 1, 2));
164
- grouped2.length && grouped.push({
165
- name: 'Grouped2',
166
- children: grouped2,
167
- columnTemplate: (h, { value }) => {
168
- return h('div', {
169
- class: 'grouped-header',
170
- }, 'Grouped2');
171
- },
311
+
312
+ if (isCanceled(isCanceledFn)) {
313
+ return null;
314
+ }
315
+
316
+ if (!rows || rows % chunkRows !== 0) {
317
+ onProgress?.({
318
+ rows,
319
+ totalRows: rows,
172
320
  });
173
- grouped.length && headers.splice(
174
- 6,
175
- 0,
176
- ...[
177
- {
178
- name: 'Grouped',
179
- children: grouped,
180
- },
181
- ],
182
- );
183
- const grouped4 = headers.splice(0, Math.min(headers.length - 1, 4));
184
- grouped4.length && headers.splice(
185
- 0,
186
- 0,
187
- ...[
188
- {
189
- name: 'Grouped3',
190
- children: grouped4,
191
- },
192
- ],
193
- );
194
321
  }
195
- return {
196
- rows: result,
322
+
323
+ return finishData({
324
+ result,
197
325
  pinnedTopRows,
198
326
  pinnedBottomRows,
199
327
  headers,
200
- };
328
+ groupedHeader,
329
+ });
201
330
  }
@@ -4,8 +4,9 @@
4
4
  import reduce from "lodash/reduce";
5
5
  import debounce from "lodash/debounce";
6
6
  import { RESIZE_INTERVAL } from "../utils/consts";
7
- import { columnTypes, rowTypes, getItemByIndex, DimensionStore, gatherTrimmedItems, } from "../store/index";
7
+ import { columnTypes, rowTypes, getItemByIndex, DimensionStore, gatherTrimmedItems, clampViewportCoordinate, } from "../store/index";
8
8
  import { getColumnSizes } from "../utils/column.utils";
9
+ import { getScrollDimension } from "./scroll.dimension.helpers";
9
10
  /**
10
11
  * Dimension provider
11
12
  * Stores dimension information and custom sizes
@@ -143,6 +144,20 @@ export default class DimensionProvider {
143
144
  }
144
145
  setViewPortCoordinate({ type, coordinate = this.viewports.stores[type].lastCoordinate, force = false, }) {
145
146
  const dimension = this.stores[type].getCurrentState();
147
+ const viewport = this.viewports.stores[type].store;
148
+ const clientSize = viewport.get('clientSize');
149
+ const viewportSize = viewport.get('virtualSize');
150
+ const scrollDimension = getScrollDimension({
151
+ contentSize: dimension.realSize,
152
+ clientSize,
153
+ virtualSize: viewportSize,
154
+ });
155
+ const renderCoordinate = clampViewportCoordinate(coordinate, dimension, viewportSize);
156
+ const renderOffset = clientSize && viewportSize
157
+ ? scrollDimension.getRenderOffset(renderCoordinate)
158
+ : 0;
159
+ this.stores[type].setStore({ renderOffset });
160
+ this.viewports.stores[type].setViewport({ renderOffset });
146
161
  this.viewports.stores[type].setViewPortCoordinate(coordinate, dimension, force);
147
162
  }
148
163
  getViewPortPos(e) {
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
- import { scaleValue } from "../utils";
4
+ import { getScrollDimension } from "./scroll.dimension.helpers";
5
5
  const initialParams = {
6
6
  contentSize: 0,
7
7
  clientSize: 0,
@@ -14,10 +14,11 @@ const NO_COORDINATE = -1;
14
14
  * return full size
15
15
  */
16
16
  export function getContentSize(contentSize, clientSize, virtualSize = 0) {
17
- if (virtualSize > contentSize) {
18
- return 0;
19
- }
20
- return contentSize + (virtualSize ? clientSize - virtualSize : 0);
17
+ return getScrollDimension({
18
+ contentSize,
19
+ clientSize,
20
+ virtualSize,
21
+ }).physicalContentSize;
21
22
  }
22
23
  export default class LocalScrollService {
23
24
  constructor(cfg) {
@@ -31,14 +32,20 @@ export default class LocalScrollService {
31
32
  rgRow: NO_COORDINATE,
32
33
  rgCol: NO_COORDINATE,
33
34
  };
35
+ this.previousLogicalScroll = {
36
+ rgRow: 0,
37
+ rgCol: 0,
38
+ };
34
39
  this.params = {
35
40
  rgRow: Object.assign({}, initialParams),
36
41
  rgCol: Object.assign({}, initialParams),
37
42
  };
38
43
  }
39
44
  setParams(params, dimension) {
40
- const virtualContentSize = getContentSize(params.contentSize, params.clientSize, params.virtualSize);
41
- this.params[dimension] = Object.assign(Object.assign({}, params), { maxSize: virtualContentSize - params.clientSize, virtualContentSize });
45
+ const scrollDimension = getScrollDimension(params);
46
+ const virtualContentSize = scrollDimension.physicalContentSize;
47
+ this.params[dimension] = Object.assign(Object.assign({}, params), { maxSize: virtualContentSize - params.clientSize, virtualContentSize,
48
+ scrollDimension });
42
49
  }
43
50
  // apply scroll values after scroll done
44
51
  async setScroll(e) {
@@ -58,16 +65,27 @@ export default class LocalScrollService {
58
65
  await frameAnimation;
59
66
  const params = this.getParams(e.dimension);
60
67
  e.coordinate = Math.ceil(e.coordinate);
61
- this.previousScroll[e.dimension] = this.wrapCoordinate(e.coordinate, params);
68
+ this.previousLogicalScroll[e.dimension] = this.wrapLogicalCoordinate(e.coordinate, params);
69
+ const physicalCoordinate = this.toPhysicalCoordinate(e.coordinate, params);
70
+ this.previousScroll[e.dimension] = this.wrapPhysicalCoordinate(physicalCoordinate, params);
62
71
  this.preventArtificialScroll[e.dimension] = null;
63
- this.cfg.applyScroll(Object.assign(Object.assign({}, e), { coordinate: params.virtualSize
64
- ? this.convert(e.coordinate, params, false)
65
- : e.coordinate }));
72
+ this.cfg.applyScroll(Object.assign(Object.assign({}, e), { coordinate: physicalCoordinate }));
66
73
  }
67
74
  catch (id) {
68
75
  window.cancelAnimationFrame(id);
69
76
  }
70
77
  }
78
+ async setScrollByDelta(e, currentPhysicalCoordinate) {
79
+ var _a;
80
+ const params = this.getParams(e.dimension);
81
+ const baseCoordinate = this.previousScroll[e.dimension] === NO_COORDINATE
82
+ ? this.toLogicalCoordinate(currentPhysicalCoordinate, params)
83
+ : this.previousLogicalScroll[e.dimension];
84
+ const coordinate = this.wrapLogicalCoordinate(baseCoordinate + ((_a = e.delta) !== null && _a !== void 0 ? _a : 0), params);
85
+ const nextEvent = Object.assign(Object.assign({}, e), { coordinate });
86
+ await this.setScroll(nextEvent);
87
+ return nextEvent;
88
+ }
71
89
  /**
72
90
  * On scroll event started
73
91
  */
@@ -80,21 +98,21 @@ export default class LocalScrollService {
80
98
  return;
81
99
  }
82
100
  const param = this.getParams(dimension);
101
+ const logicalCoordinate = this.toLogicalScrollCoordinate(coordinate, dimension, param, delta);
83
102
  // let component know about scroll event started
84
103
  this.cfg.runScroll({
85
104
  dimension: dimension,
86
- coordinate: param.virtualSize
87
- ? this.convert(coordinate, param)
88
- : coordinate,
105
+ coordinate: logicalCoordinate,
89
106
  delta,
90
107
  outside,
91
108
  });
109
+ this.previousLogicalScroll[dimension] = logicalCoordinate;
92
110
  }
93
111
  getParams(dimension) {
94
112
  return this.params[dimension];
95
113
  }
96
114
  // check if scroll outside of region to avoid looping
97
- wrapCoordinate(c, param) {
115
+ wrapPhysicalCoordinate(c, param) {
98
116
  if (c < 0) {
99
117
  return NO_COORDINATE;
100
118
  }
@@ -103,21 +121,38 @@ export default class LocalScrollService {
103
121
  }
104
122
  return c;
105
123
  }
124
+ wrapLogicalCoordinate(c, param) {
125
+ var _a, _b;
126
+ if (c < 0) {
127
+ return 0;
128
+ }
129
+ return Math.min(c, (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.logicalScrollSize) !== null && _b !== void 0 ? _b : c);
130
+ }
106
131
  // prevent already started scroll, performance optimization
107
132
  cancelScroll(dimension) {
108
133
  var _a, _b;
109
134
  (_b = (_a = this.preventArtificialScroll)[dimension]) === null || _b === void 0 ? void 0 : _b.call(_a);
110
135
  this.preventArtificialScroll[dimension] = null;
111
136
  }
112
- /* convert virtual to real and back, scale range */
113
- convert(pos, param, toReal = true) {
114
- var _a;
115
- const minRange = param.clientSize;
116
- const from = [0, ((_a = param.virtualContentSize) !== null && _a !== void 0 ? _a : minRange) - minRange];
117
- const to = [0, param.contentSize - param.virtualSize];
118
- if (toReal) {
119
- return scaleValue(pos, from, to);
137
+ toLogicalScrollCoordinate(coordinate, dimension, param, delta) {
138
+ const scrollDimension = param.scrollDimension;
139
+ if (!scrollDimension) {
140
+ return coordinate;
120
141
  }
121
- return scaleValue(pos, to, from);
142
+ if (typeof delta === 'number' && scrollDimension.isCompressed) {
143
+ const base = this.previousScroll[dimension] === NO_COORDINATE
144
+ ? scrollDimension.toLogicalCoordinate(coordinate - delta)
145
+ : this.previousLogicalScroll[dimension];
146
+ return scrollDimension.toLogicalCoordinate(scrollDimension.toPhysicalCoordinate(base + delta));
147
+ }
148
+ return scrollDimension.toLogicalCoordinate(coordinate);
149
+ }
150
+ toPhysicalCoordinate(coordinate, param) {
151
+ var _a, _b;
152
+ return (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.toPhysicalCoordinate(coordinate)) !== null && _b !== void 0 ? _b : coordinate;
153
+ }
154
+ toLogicalCoordinate(coordinate, param) {
155
+ var _a, _b;
156
+ return (_b = (_a = param.scrollDimension) === null || _a === void 0 ? void 0 : _a.toLogicalCoordinate(coordinate)) !== null && _b !== void 0 ? _b : coordinate;
122
157
  }
123
158
  }