@revolist/revogrid 4.27.0 → 4.27.2

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 (76) hide show
  1. package/dist/cjs/{cell-renderer-C7rdgaov.js → cell-renderer-BDIx0xys.js} +1 -1
  2. package/dist/cjs/{column.service-Bbml5C2j.js → column.service-D-ENzqyb.js} +2 -0
  3. package/dist/cjs/{filter.button-F2Bw3UAd.js → filter.button-C6ixuMmr.js} +3 -2
  4. package/dist/cjs/{header-cell-renderer-BljFI6wj.js → header-cell-renderer-B5Y4fdZC.js} +1 -1
  5. package/dist/cjs/index.cjs.js +7 -5
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/cjs/revo-grid.cjs.entry.js +63 -43
  8. package/dist/cjs/revo-grid.cjs.js +1 -1
  9. package/dist/cjs/revogr-attribution_7.cjs.entry.js +1 -1
  10. package/dist/cjs/revogr-data_4.cjs.entry.js +12 -11
  11. package/dist/cjs/revogr-filter-panel.cjs.entry.js +139 -33
  12. package/dist/cjs/{row-resize.plugin-BRQy_qNn.js → row-resize.plugin-C4YOF1lN.js} +353 -185
  13. package/dist/collection/components/header/header-renderer.js +7 -6
  14. package/dist/collection/components/header/revogr-header-style.css +8 -3
  15. package/dist/collection/components/revoGrid/revo-grid-style.css +12 -2
  16. package/dist/collection/components/revoGrid/revo-grid.js +37 -21
  17. package/dist/collection/plugins/filter/filter.button.js +3 -2
  18. package/dist/collection/plugins/filter/filter.indexed.js +5 -0
  19. package/dist/collection/plugins/filter/filter.panel.js +138 -31
  20. package/dist/collection/plugins/filter/filter.plugin.js +48 -5
  21. package/dist/collection/plugins/filter/filter.style.css +25 -3
  22. package/dist/collection/plugins/groupingRow/grouping.const.js +1 -0
  23. package/dist/collection/plugins/groupingRow/grouping.row.plugin.js +84 -54
  24. package/dist/collection/plugins/groupingRow/grouping.sorting.service.js +58 -0
  25. package/dist/collection/plugins/groupingRow/grouping.trimmed.service.js +5 -3
  26. package/dist/collection/plugins/row-resize/row-resize.plugin.js +144 -113
  27. package/dist/collection/plugins/sorting/sorting.plugin.js +16 -13
  28. package/dist/collection/plugins/wcag/index.js +5 -4
  29. package/dist/collection/services/dimension.provider.js +17 -1
  30. package/dist/esm/{cell-renderer-BFpmdV8H.js → cell-renderer-D9ze8OJw.js} +1 -1
  31. package/dist/esm/{column.service-CM-wgGs8.js → column.service-pu_fdQ0S.js} +2 -1
  32. package/dist/esm/{filter.button-DMhpuAiw.js → filter.button-CEPUxLUo.js} +3 -2
  33. package/dist/{revo-grid/header-cell-renderer-Bqh1PrgH.js → esm/header-cell-renderer-YCiVIQ2E.js} +1 -1
  34. package/dist/esm/index.js +6 -6
  35. package/dist/esm/loader.js +1 -1
  36. package/dist/esm/revo-grid.entry.js +63 -43
  37. package/dist/esm/revo-grid.js +1 -1
  38. package/dist/esm/revogr-attribution_7.entry.js +1 -1
  39. package/dist/esm/revogr-data_4.entry.js +12 -11
  40. package/dist/esm/revogr-filter-panel.entry.js +139 -33
  41. package/dist/esm/{row-resize.plugin-BRiaHlHA.js → row-resize.plugin-Beu0pMds.js} +354 -187
  42. package/dist/revo-grid/{cell-renderer-BFpmdV8H.js → cell-renderer-D9ze8OJw.js} +1 -1
  43. package/dist/revo-grid/{column.service-CM-wgGs8.js → column.service-pu_fdQ0S.js} +2 -1
  44. package/dist/revo-grid/{filter.button-DMhpuAiw.js → filter.button-CEPUxLUo.js} +3 -2
  45. package/dist/{esm/header-cell-renderer-Bqh1PrgH.js → revo-grid/header-cell-renderer-YCiVIQ2E.js} +1 -1
  46. package/dist/revo-grid/index.esm.js +6 -6
  47. package/dist/revo-grid/revo-grid.entry.js +63 -43
  48. package/dist/revo-grid/revo-grid.esm.js +1 -1
  49. package/dist/revo-grid/revogr-attribution_7.entry.js +1 -1
  50. package/dist/revo-grid/revogr-data_4.entry.js +12 -11
  51. package/dist/revo-grid/revogr-filter-panel.entry.js +139 -33
  52. package/dist/revo-grid/{row-resize.plugin-BRiaHlHA.js → row-resize.plugin-Beu0pMds.js} +354 -187
  53. package/dist/types/components/revoGrid/revo-grid.d.ts +2 -0
  54. package/dist/types/plugins/filter/filter.indexed.d.ts +2 -0
  55. package/dist/types/plugins/filter/filter.panel.d.ts +9 -2
  56. package/dist/types/plugins/filter/filter.plugin.d.ts +8 -1
  57. package/dist/types/plugins/filter/filter.types.d.ts +8 -0
  58. package/dist/types/plugins/groupingRow/grouping.const.d.ts +1 -0
  59. package/dist/types/plugins/groupingRow/grouping.row.plugin.d.ts +5 -7
  60. package/dist/types/plugins/groupingRow/grouping.sorting.service.d.ts +7 -0
  61. package/dist/types/plugins/groupingRow/grouping.trimmed.service.d.ts +9 -0
  62. package/dist/types/plugins/row-resize/row-resize.plugin.d.ts +14 -12
  63. package/dist/types/plugins/sorting/sorting.plugin.d.ts +5 -0
  64. package/dist/types/services/dimension.provider.d.ts +7 -1
  65. package/dist/types/types/interfaces.d.ts +13 -1
  66. package/hydrate/index.js +561 -264
  67. package/hydrate/index.mjs +561 -264
  68. package/package.json +1 -1
  69. package/standalone/column.service.js +1 -1
  70. package/standalone/filter.button.js +1 -1
  71. package/standalone/index.js +1 -1
  72. package/standalone/revo-grid.js +1 -1
  73. package/standalone/revogr-data2.js +1 -1
  74. package/standalone/revogr-filter-panel.js +1 -1
  75. package/standalone/revogr-header2.js +1 -1
  76. package/standalone/revogr-overlay-selection2.js +1 -1
@@ -3,14 +3,14 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- var column_service = require('./column.service-Bbml5C2j.js');
6
+ var column_service = require('./column.service-D-ENzqyb.js');
7
7
  var dimension_helpers = require('./dimension.helpers-CptesQOZ.js');
8
8
  var viewport_store = require('./viewport.store-mhsdi61t.js');
9
9
  var index$1 = require('./index-BVESmpqW.js');
10
10
  var index = require('./index-DRvxCueo.js');
11
- var filter_button = require('./filter.button-F2Bw3UAd.js');
11
+ var filter_button = require('./filter.button-C6ixuMmr.js');
12
12
  var debounce = require('./debounce-CcpHiH2p.js');
13
- var headerCellRenderer = require('./header-cell-renderer-BljFI6wj.js');
13
+ var headerCellRenderer = require('./header-cell-renderer-B5Y4fdZC.js');
14
14
 
15
15
  /**
16
16
  * Public theme tokens and their CSS custom-property counterparts.
@@ -1363,6 +1363,11 @@ const filterTypes = {
1363
1363
  boolean: ['notEmpty', 'empty'],
1364
1364
  array: ['notEmpty', 'empty'],
1365
1365
  };
1366
+ /** Preferred initial operator for built-in filter families. */
1367
+ const filterTypeDefaults = {
1368
+ string: 'contains',
1369
+ number: 'eqN',
1370
+ };
1366
1371
  const filterNames = {
1367
1372
  none: 'None',
1368
1373
  empty: 'Is blank',
@@ -1405,6 +1410,8 @@ const FILTE_PANEL = 'revogr-filter-panel';
1405
1410
  *
1406
1411
  * @property {FilterLocalization|undefined} localization - translation for filter popup captions.
1407
1412
  *
1413
+ * @property {boolean|undefined} defaultFilter - creates a draft condition when an empty filter panel opens. Defaults to true.
1414
+ *
1408
1415
  * @property {boolean|undefined} disableDynamicFiltering - disables dynamic filtering. A way to apply filters on Save only.
1409
1416
  */
1410
1417
  /**
@@ -1426,7 +1433,7 @@ class FilterPlugin extends BasePlugin {
1426
1433
  * number: ['eqN', 'neqN', 'gt']
1427
1434
  * }
1428
1435
  */
1429
- this.filterByType = Object.assign({}, filterTypes);
1436
+ this.filterByType = Object.fromEntries(Object.entries(filterTypes).map(([type, filters]) => [type, [...filters]]));
1430
1437
  this.filterNameIndexByType = Object.assign({}, filterNames);
1431
1438
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
1432
1439
  this.filterProp = filter_button.FILTER_PROP;
@@ -1510,11 +1517,16 @@ class FilterPlugin extends BasePlugin {
1510
1517
  return null;
1511
1518
  }
1512
1519
  initConfig(config) {
1513
- var _a;
1520
+ var _a, _b, _c, _d;
1514
1521
  this.config = config;
1515
1522
  this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
1516
1523
  if (this.pop) {
1517
1524
  this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
1525
+ this.pop.disableDynamicFiltering =
1526
+ (_b = config.disableDynamicFiltering) !== null && _b !== void 0 ? _b : false;
1527
+ this.pop.closeOnOutsideClick =
1528
+ (_c = config.closeFilterPanelOnOutsideClick) !== null && _c !== void 0 ? _c : true;
1529
+ this.pop.filterCaptions = (_d = config.localization) === null || _d === void 0 ? void 0 : _d.captions;
1518
1530
  }
1519
1531
  if (config.multiFilterItems) {
1520
1532
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
@@ -1603,11 +1615,12 @@ class FilterPlugin extends BasePlugin {
1603
1615
  }
1604
1616
  // filter button clicked, open filter dialog
1605
1617
  const buttonPos = (filterButton instanceof HTMLElement ? filterButton : el).getBoundingClientRect();
1606
- const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
1618
+ const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), defaultFilterType: this.getDefaultFilter(e.detail.filter), showDefaultFilter: this.shouldShowDefaultFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
1607
1619
  (_b = this.beforeshow) === null || _b === void 0 ? void 0 : _b.call(this, data);
1608
1620
  this.pop.show(data);
1609
1621
  }
1610
- getColumnFilter(type) {
1622
+ getColumnFilter(config) {
1623
+ const type = this.isColumnFilterOption(config) ? config.type : config;
1611
1624
  let filterType = 'string';
1612
1625
  if (!type) {
1613
1626
  return { [filterType]: this.filterByType[filterType] };
@@ -1627,6 +1640,41 @@ class FilterPlugin extends BasePlugin {
1627
1640
  }
1628
1641
  return { [filterType]: this.filterByType[filterType] };
1629
1642
  }
1643
+ /** Resolve the preferred operator against the column's available filters. */
1644
+ getDefaultFilter(config) {
1645
+ var _a;
1646
+ const filters = this.getColumnFilter(config);
1647
+ const availableFilters = Object.values(filters).flat();
1648
+ const columnDefault = this.isColumnFilterOption(config)
1649
+ ? config.default
1650
+ : undefined;
1651
+ if (typeof columnDefault === 'string' &&
1652
+ availableFilters.includes(columnDefault)) {
1653
+ return columnDefault;
1654
+ }
1655
+ const firstFamily = Object.keys(filters)[0];
1656
+ const familyDefault = filterTypeDefaults[firstFamily];
1657
+ if (familyDefault && ((_a = filters[firstFamily]) === null || _a === void 0 ? void 0 : _a.includes(familyDefault))) {
1658
+ return familyDefault;
1659
+ }
1660
+ return availableFilters[0];
1661
+ }
1662
+ /** Resolve grid and column-level draft opt-outs. */
1663
+ shouldShowDefaultFilter(config) {
1664
+ var _a;
1665
+ if (this.isColumnFilterOption(config)) {
1666
+ if (config.default === false) {
1667
+ return false;
1668
+ }
1669
+ if (typeof config.default === 'string') {
1670
+ return true;
1671
+ }
1672
+ }
1673
+ return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.defaultFilter) !== false;
1674
+ }
1675
+ isColumnFilterOption(value) {
1676
+ return !!value && typeof value === 'object' && !Array.isArray(value);
1677
+ }
1630
1678
  isValidType(type) {
1631
1679
  return !!(typeof type === 'string' && this.filterByType[type]);
1632
1680
  }
@@ -1909,6 +1957,60 @@ function allAndConditionsSatisfied(pendingResults) {
1909
1957
  return !pendingResults.includes(true);
1910
1958
  }
1911
1959
 
1960
+ /**
1961
+ * Restores group headers around already-sorted data indexes without rebuilding
1962
+ * the physical source. Group insertion order follows the first sorted member,
1963
+ * matching the order produced by regrouping a sorted source.
1964
+ */
1965
+ function gatherGroupedRowIndexes(source, sortedDataIndexes) {
1966
+ const groupPathByDataIndex = new Map();
1967
+ const currentGroupPath = [];
1968
+ source.forEach((model, physicalIndex) => {
1969
+ if (column_service.isGrouping(model)) {
1970
+ const depth = model[column_service.GROUP_DEPTH];
1971
+ if (typeof depth !== 'number') {
1972
+ return;
1973
+ }
1974
+ currentGroupPath.length = depth;
1975
+ currentGroupPath[depth] = physicalIndex;
1976
+ return;
1977
+ }
1978
+ if (model != null) {
1979
+ groupPathByDataIndex.set(physicalIndex, [...currentGroupPath]);
1980
+ }
1981
+ });
1982
+ const root = {
1983
+ children: new Map(),
1984
+ items: [],
1985
+ };
1986
+ for (const physicalIndex of sortedDataIndexes) {
1987
+ const groupPath = groupPathByDataIndex.get(physicalIndex);
1988
+ if (!(groupPath === null || groupPath === void 0 ? void 0 : groupPath.length)) {
1989
+ return undefined;
1990
+ }
1991
+ let node = root;
1992
+ for (const groupIndex of groupPath) {
1993
+ let child = node.children.get(groupIndex);
1994
+ if (!child) {
1995
+ child = { children: new Map(), items: [] };
1996
+ node.children.set(groupIndex, child);
1997
+ }
1998
+ node = child;
1999
+ }
2000
+ node.items.push(physicalIndex);
2001
+ }
2002
+ const groupedIndexes = [];
2003
+ const appendNode = (node) => {
2004
+ node.children.forEach((child, groupIndex) => {
2005
+ groupedIndexes.push(groupIndex);
2006
+ appendNode(child);
2007
+ });
2008
+ groupedIndexes.push(...node.items);
2009
+ };
2010
+ appendNode(root);
2011
+ return groupedIndexes;
2012
+ }
2013
+
1912
2014
  /**
1913
2015
  * Checks whether a sorting map contains at least one active order.
1914
2016
  *
@@ -2146,18 +2248,6 @@ function getComparer(column, order) {
2146
2248
  function getSortableRowIndexes(indexes, source) {
2147
2249
  return indexes.filter(index => !column_service.isGrouping(source[index]));
2148
2250
  }
2149
- function mergeSortedRowsWithGroups(indexes, source, sortedRows) {
2150
- if (sortedRows.length === indexes.length) {
2151
- return sortedRows;
2152
- }
2153
- let rowIndex = 0;
2154
- return indexes.map(index => {
2155
- if (column_service.isGrouping(source[index])) {
2156
- return index;
2157
- }
2158
- return sortedRows[rowIndex++];
2159
- });
2160
- }
2161
2251
  /**
2162
2252
  * Lifecycle
2163
2253
  * 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.
@@ -2317,6 +2407,7 @@ class SortingPlugin extends BasePlugin {
2317
2407
  storeService.setData({ proxyItems: newItemsOrder });
2318
2408
  }
2319
2409
  applySortingForStore(type, sorting, sortingFunc, sortingColumns, sortingOrder, ignoreViewportUpdate) {
2410
+ var _a;
2320
2411
  const storeService = this.providers.data.stores[type];
2321
2412
  // row data
2322
2413
  const source = storeService.store.get('source');
@@ -2324,7 +2415,10 @@ class SortingPlugin extends BasePlugin {
2324
2415
  const proxyItems = storeService.store.get('proxyItems');
2325
2416
  const sortItems = getSortableRowIndexes(proxyItems, source);
2326
2417
  const sortedItems = sortIndexByItems([...sortItems], source, sortingFunc, sorting, sortingColumns, sortingOrder);
2327
- const newItemsOrder = mergeSortedRowsWithGroups(proxyItems, source, sortedItems);
2418
+ const hasGroupingRows = sortedItems.length !== proxyItems.length;
2419
+ const newItemsOrder = hasGroupingRows
2420
+ ? (_a = gatherGroupedRowIndexes(source, sortedItems)) !== null && _a !== void 0 ? _a : proxyItems
2421
+ : sortedItems;
2328
2422
  // take row indexes before trim applied and proxy items
2329
2423
  const prevItems = storeService.store.get('items');
2330
2424
  storeService.setData({
@@ -2350,6 +2444,16 @@ class SortingPlugin extends BasePlugin {
2350
2444
  }
2351
2445
  this.postponeSort(order, sortingFunc, sortingColumns, sortingOrder, ignoreViewportUpdate);
2352
2446
  }
2447
+ /**
2448
+ * Schedules the current active sort again after another plugin rebuilds row
2449
+ * proxy indexes while keeping the physical source unchanged.
2450
+ */
2451
+ reapplySorting() {
2452
+ if (!hasActiveSorting(this.sorting) || !this.sortingFunc) {
2453
+ return;
2454
+ }
2455
+ this.startSorting(this.sorting, this.sortingFunc, this.sortingColumns, this.sortingOrder);
2456
+ }
2353
2457
  /**
2354
2458
  * Applies sorting requested by a sortable header click.
2355
2459
  *
@@ -2533,8 +2637,10 @@ const TRIMMED_GROUPING = 'grouping';
2533
2637
  * against the grouped physical source can still be remapped. If neither path
2534
2638
  * resolves to a number, the caller drops the stale trim entry.
2535
2639
  */
2536
- function convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap) {
2537
- const sourceIndex = Number.parseInt(initialIndex, 10);
2640
+ function convertGroupingIndex(initialIndex, firstLevelMap, secondLevelMap) {
2641
+ const sourceIndex = typeof initialIndex === 'number'
2642
+ ? initialIndex
2643
+ : Number.parseInt(initialIndex, 10);
2538
2644
  const firstConversionIndex = firstLevelMap[sourceIndex];
2539
2645
  if (!secondLevelMap) {
2540
2646
  return firstConversionIndex;
@@ -2567,7 +2673,7 @@ function processDoubleConversionTrimmed(initiallyTrimed, firstLevelMap, secondLe
2567
2673
  * if item exists we find it in collection
2568
2674
  * we support 2 level of conversions
2569
2675
  */
2570
- const newConversionIndex = convertTrimmedIndex(initialIndex, firstLevelMap, secondLevelMap);
2676
+ const newConversionIndex = convertGroupingIndex(initialIndex, firstLevelMap, secondLevelMap);
2571
2677
  // Group rows do not exist in the ungrouped index map and must not leak into new trims.
2572
2678
  if (typeof newConversionIndex !== 'number') {
2573
2679
  continue;
@@ -2628,18 +2734,6 @@ function filterOutEmptyGroupRows(source, filterTrimmed) {
2628
2734
  return trimmed;
2629
2735
  }
2630
2736
 
2631
- var __rest = (undefined && undefined.__rest) || function (s, e) {
2632
- var t = {};
2633
- for (var p in s)
2634
- if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
2635
- t[p] = s[p];
2636
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
2637
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
2638
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
2639
- t[p[i]] = s[p[i]];
2640
- }
2641
- return t;
2642
- };
2643
2737
  class GroupingRowPlugin extends BasePlugin {
2644
2738
  getStore(type = column_service.GROUPING_ROW_TYPE) {
2645
2739
  return this.providers.data.stores[type].store;
@@ -2655,15 +2749,16 @@ class GroupingRowPlugin extends BasePlugin {
2655
2749
  }
2656
2750
  // expand event triggered
2657
2751
  onExpand({ virtualIndex }) {
2658
- const { source } = column_service.getSource(this.getStore().get('source'), this.getStore().get('proxyItems'));
2659
- let newTrimmed = this.getStore().get('trimmed')[TRIMMED_GROUPING];
2660
- let i = dimension_helpers.getPhysical(this.getStore(), virtualIndex);
2752
+ const store = this.getStore();
2753
+ const source = store.get('source');
2754
+ let newTrimmed = store.get('trimmed')[TRIMMED_GROUPING];
2755
+ const i = dimension_helpers.getPhysical(store, virtualIndex);
2661
2756
  const isExpanded = column_service.getExpanded(source[i]);
2662
2757
  if (!isExpanded) {
2663
- const { trimmed, items } = doExpand(virtualIndex, source, this.getStore().get('items'));
2758
+ const { trimmed, items: expandedItems } = doExpand(virtualIndex, source, store.get('items'));
2664
2759
  newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
2665
- if (items) {
2666
- dimension_helpers.setItems(this.getStore(), items);
2760
+ if (expandedItems) {
2761
+ dimension_helpers.setItems(store, expandedItems);
2667
2762
  }
2668
2763
  }
2669
2764
  else {
@@ -2671,7 +2766,7 @@ class GroupingRowPlugin extends BasePlugin {
2671
2766
  newTrimmed = Object.assign(Object.assign({}, newTrimmed), trimmed);
2672
2767
  this.revogrid.clearFocus();
2673
2768
  }
2674
- this.getStore().set('source', source);
2769
+ store.set('source', source);
2675
2770
  this.revogrid.addTrimmed(newTrimmed, TRIMMED_GROUPING);
2676
2771
  }
2677
2772
  setColumnGrouping(cols) {
@@ -2693,7 +2788,7 @@ class GroupingRowPlugin extends BasePlugin {
2693
2788
  onDrag(e) {
2694
2789
  const { from, to } = e.detail;
2695
2790
  const isDown = to - from >= 0;
2696
- const { source } = column_service.getSource(this.getStore().get('source'), this.getStore().get('proxyItems'));
2791
+ const source = this.getStore().get('source');
2697
2792
  const items = this.getStore().get('items');
2698
2793
  let i = isDown ? from : to;
2699
2794
  const end = isDown ? to : from;
@@ -2719,21 +2814,13 @@ class GroupingRowPlugin extends BasePlugin {
2719
2814
  const source = this.getStore().get('source');
2720
2815
  return filterOutEmptyGroupRows(source, trimmed);
2721
2816
  }
2722
- isSortingRunning() {
2723
- const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
2724
- return !!(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sortingPromise);
2725
- }
2726
2817
  /**
2727
- * Returns grouping options for regrouping that must preserve current UI state.
2728
- *
2729
- * `expandedAll` and config `prevExpanded` are initial/config instructions.
2730
- * Reusing them after sorting would reopen groups the user collapsed before
2731
- * sorting instead of using the current grouped source state.
2818
+ * Sorting changes proxy order without changing the physical source baseline.
2819
+ * Other proxy changes, such as row dragging, are user-authored source order
2820
+ * and must be retained when grouping is rebuilt.
2732
2821
  */
2733
- getCurrentExpandedOptions() {
2734
- var _a;
2735
- const _b = (_a = this.options) !== null && _a !== void 0 ? _a : {}, options = __rest(_b, ["expandedAll", "prevExpanded"]);
2736
- return options;
2822
+ isSortingActiveOrPending(sortingPlugin) {
2823
+ return !!(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sortingPromise) || hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting);
2737
2824
  }
2738
2825
  /**
2739
2826
  * Starts global source update with group clearing and applying new one
@@ -2746,7 +2833,12 @@ class GroupingRowPlugin extends BasePlugin {
2746
2833
  * @param newOldIndexMap - provides us mapping with new indexes vs old indexes, we would use it for trimmed mapping
2747
2834
  */
2748
2835
  const store = this.getStore();
2749
- const { source, prevExpanded, oldNewIndexes } = column_service.getSource(store.get('source'), store.get('proxyItems'), true);
2836
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
2837
+ const currentSource = store.get('source');
2838
+ const sourceItems = this.isSortingActiveOrPending(sortingPlugin)
2839
+ ? currentSource.map((_, index) => index)
2840
+ : store.get('proxyItems');
2841
+ const { source, prevExpanded, oldNewIndexes } = column_service.getSource(currentSource, sourceItems, true);
2750
2842
  const expanded = Object.assign({ prevExpanded }, options);
2751
2843
  /**
2752
2844
  * Group again
@@ -2756,8 +2848,13 @@ class GroupingRowPlugin extends BasePlugin {
2756
2848
  const customRenderer = options === null || options === void 0 ? void 0 : options.groupLabelTemplate;
2757
2849
  const cellRenderer = options === null || options === void 0 ? void 0 : options.groupCellTemplate;
2758
2850
  // setup source
2851
+ this.revogrid.dispatchEvent(new CustomEvent(column_service.BEFORE_GROUPING_APPLY_EVENT));
2759
2852
  this.providers.data.setData(sourceWithGroups, column_service.GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, { depth, customRenderer, cellRenderer }, true);
2853
+ this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, currentSource, sourceWithGroups);
2760
2854
  this.updateTrimmed(trimmed, oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, sourceWithGroups);
2855
+ if (hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting)) {
2856
+ sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.reapplySorting();
2857
+ }
2761
2858
  }
2762
2859
  /**
2763
2860
  * Apply grouping on data set
@@ -2766,9 +2863,14 @@ class GroupingRowPlugin extends BasePlugin {
2766
2863
  */
2767
2864
  onDataSet(data) {
2768
2865
  var _a, _b, _c;
2866
+ const currentSource = this.getStore().get('source');
2867
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
2868
+ const currentItems = this.isSortingActiveOrPending(sortingPlugin)
2869
+ ? currentSource.map((_, index) => index)
2870
+ : this.getStore().get('proxyItems');
2871
+ const { prevExpanded, oldNewIndexes } = column_service.getSource(currentSource, currentItems, true);
2769
2872
  let preservedExpanded = {};
2770
2873
  if (((_a = this.options) === null || _a === void 0 ? void 0 : _a.preserveGroupingOnUpdate) !== false) {
2771
- let { prevExpanded } = column_service.getSource(this.getStore().get('source'), this.getStore().get('proxyItems'), true);
2772
2874
  preservedExpanded = prevExpanded;
2773
2875
  }
2774
2876
  const source = data.source.filter(s => !column_service.isGrouping(s));
@@ -2780,6 +2882,7 @@ class GroupingRowPlugin extends BasePlugin {
2780
2882
  customRenderer: options.groupLabelTemplate,
2781
2883
  cellRenderer: options.groupCellTemplate,
2782
2884
  });
2885
+ queueMicrotask(() => this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, oldNewIndexMap, currentSource, sourceWithGroups));
2783
2886
  this.updateTrimmed(trimmed, oldNewIndexMap, undefined, sourceWithGroups, { filterTrimmedMode: 'recompute-after-source-set' });
2784
2887
  }
2785
2888
  /**
@@ -2815,10 +2918,6 @@ class GroupingRowPlugin extends BasePlugin {
2815
2918
  if (!(((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.length) && ((_c = detail === null || detail === void 0 ? void 0 : detail.source) === null || _c === void 0 ? void 0 : _c.length))) {
2816
2919
  return;
2817
2920
  }
2818
- // if sorting is running don't apply grouping, wait for sorting, then it'll apply in @aftersortingapply
2819
- if (this.isSortingRunning()) {
2820
- return;
2821
- }
2822
2921
  this.onDataSet(detail);
2823
2922
  });
2824
2923
  this.addEventListener('beforecolumnsset', ({ detail }) => {
@@ -2833,17 +2932,6 @@ class GroupingRowPlugin extends BasePlugin {
2833
2932
  this.addEventListener('beforefiltertrimmed', ({ detail }) => {
2834
2933
  detail.itemsToFilter = this.beforeFilterTrimmed(detail.itemsToFilter);
2835
2934
  });
2836
- /**
2837
- * sorting applied need to clear grouping and apply again
2838
- * based on new results whole grouping order will changed
2839
- */
2840
- this.addEventListener('aftersortingapply', () => {
2841
- var _a, _b;
2842
- if (!((_b = (_a = this.options) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.length)) {
2843
- return;
2844
- }
2845
- this.doSourceUpdate(this.getCurrentExpandedOptions());
2846
- });
2847
2935
  /**
2848
2936
  * Apply logic for focus inside of grouping
2849
2937
  * We can't focus on grouping rows, navigation only inside of groups for now
@@ -2876,9 +2964,57 @@ class GroupingRowPlugin extends BasePlugin {
2876
2964
  }
2877
2965
  });
2878
2966
  // clear rows
2879
- const { source, oldNewIndexes } = column_service.getSource(this.getStore().get('source'), this.getStore().get('proxyItems'), true);
2967
+ const store = this.getStore();
2968
+ const sortingPlugin = this.providers.plugins.getByClass(SortingPlugin);
2969
+ const currentSource = store.get('source');
2970
+ const sourceItems = this.isSortingActiveOrPending(sortingPlugin)
2971
+ ? currentSource.map((_, index) => index)
2972
+ : store.get('proxyItems');
2973
+ const { source, oldNewIndexes } = column_service.getSource(currentSource, sourceItems, true);
2974
+ this.revogrid.dispatchEvent(new CustomEvent(column_service.BEFORE_GROUPING_APPLY_EVENT));
2880
2975
  this.providers.data.setData(source, column_service.GROUPING_ROW_TYPE, this.revogrid.disableVirtualY, undefined, true);
2976
+ this.remapRowDefinitions(oldNewIndexes !== null && oldNewIndexes !== void 0 ? oldNewIndexes : {}, undefined, currentSource, source);
2881
2977
  this.updateTrimmed(undefined, undefined, oldNewIndexes, source);
2978
+ if (hasActiveSorting(sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.sorting)) {
2979
+ sortingPlugin === null || sortingPlugin === void 0 ? void 0 : sortingPlugin.reapplySorting();
2980
+ }
2981
+ }
2982
+ remapRowDefinitions(firstLevelMap, secondLevelMap, previousSource, nextSource) {
2983
+ const definitions = this.providers.dimension.getRowDefinitions();
2984
+ const nextGroupIndexes = new Map();
2985
+ nextSource === null || nextSource === void 0 ? void 0 : nextSource.forEach((row, index) => {
2986
+ const groupId = row[column_service.PSEUDO_GROUP_ITEM_ID];
2987
+ if (groupId && !nextGroupIndexes.has(groupId)) {
2988
+ nextGroupIndexes.set(groupId, index);
2989
+ }
2990
+ });
2991
+ let changed = false;
2992
+ const remapped = definitions.flatMap(definition => {
2993
+ if (definition.type !== column_service.GROUPING_ROW_TYPE) {
2994
+ return [definition];
2995
+ }
2996
+ const previousRow = previousSource === null || previousSource === void 0 ? void 0 : previousSource[definition.index];
2997
+ const groupId = previousRow === null || previousRow === void 0 ? void 0 : previousRow[column_service.PSEUDO_GROUP_ITEM_ID];
2998
+ const index = groupId
2999
+ ? nextGroupIndexes.get(groupId)
3000
+ : convertGroupingIndex(definition.index, firstLevelMap, secondLevelMap);
3001
+ if (typeof index !== 'number') {
3002
+ changed = true;
3003
+ return [];
3004
+ }
3005
+ if (index < 0) {
3006
+ changed = true;
3007
+ return [];
3008
+ }
3009
+ if (index === definition.index) {
3010
+ return [definition];
3011
+ }
3012
+ changed = true;
3013
+ return [Object.assign(Object.assign({}, definition), { index })];
3014
+ });
3015
+ if (changed) {
3016
+ this.providers.dimension.setRowDefinitions(remapped);
3017
+ }
2882
3018
  }
2883
3019
  updateTrimmed(trimmedGroup = {}, firstLevelMap = {}, secondLevelMap, source = this.getStore().get('source'), { filterTrimmedMode = 'remap', } = {}) {
2884
3020
  // map previously trimmed data
@@ -3219,18 +3355,14 @@ const ROW_RESIZE_EVENT = 'rowresize';
3219
3355
  const AFTER_ROW_RESIZE_EVENT = 'afterrowresize';
3220
3356
  const ROW_RESIZE_CANCEL_EVENT = 'rowresizecancel';
3221
3357
  class RowResizePlugin extends BasePlugin {
3222
- static fromGridProperty(revogrid, providers) {
3223
- const plugin = new RowResizePlugin(revogrid, providers);
3224
- plugin.controlFromGridProperty();
3225
- return plugin;
3226
- }
3227
3358
  constructor(revogrid, providers, config = {}) {
3228
3359
  super(revogrid, providers);
3229
3360
  this.enabled = false;
3230
- this.gridResizeRow = false;
3231
- this.gridPlugins = [];
3232
- this.committedSizes = new Map();
3233
- this.appliedIndexes = new Map();
3361
+ this.appliedDefinitionIndexes = new Map();
3362
+ this.pendingBottomAnchor = false;
3363
+ this.keepBottomAnchor = false;
3364
+ this.rowDefinitionRemapQueued = false;
3365
+ this.pendingSourceCounts = new Map();
3234
3366
  this.previousBodyCursor = '';
3235
3367
  this.decorateRow = ({ detail, }) => {
3236
3368
  if (!this.enabled ||
@@ -3294,22 +3426,72 @@ class RowResizePlugin extends BasePlugin {
3294
3426
  }
3295
3427
  };
3296
3428
  this.onWindowBlur = () => this.cancel('blur');
3297
- this.reapplyCommittedSizes = () => this.applyCommittedSizes(false);
3298
- this.rebuildCommittedSizes = () => this.applyCommittedSizes(true);
3299
- this.syncAppliedIndexes = () => {
3300
- for (const [rowType, committed] of this.committedSizes) {
3429
+ this.updateBottomAnchorState = ({ detail, }) => {
3430
+ if (detail.dimension !== 'rgRow') {
3431
+ return;
3432
+ }
3433
+ this.keepBottomAnchor = this.isMainViewportAtBottom(detail.coordinate);
3434
+ };
3435
+ this.applyPendingBottomAnchor = () => {
3436
+ if (!this.pendingBottomAnchor) {
3437
+ return;
3438
+ }
3439
+ this.pendingBottomAnchor = false;
3440
+ const dimension = this.providers.dimension.stores.rgRow.store;
3441
+ // Scroll surfaces have slightly different client sizes. Give the shared
3442
+ // scrolling service the content end and let each surface clamp to its own
3443
+ // exact bottom coordinate.
3444
+ void this.revogrid.scrollToCoordinate({ y: dimension.get('realSize') });
3445
+ };
3446
+ this.scheduleRowDefinitionRemap = () => {
3447
+ if (this.rowDefinitionRemapQueued) {
3448
+ return;
3449
+ }
3450
+ this.rowDefinitionRemapQueued = true;
3451
+ queueMicrotask(() => {
3452
+ if (!this.rowDefinitionRemapQueued) {
3453
+ return;
3454
+ }
3455
+ this.pruneRowDefinitions();
3456
+ this.reapplyRowDefinitionSizes();
3457
+ this.rowDefinitionRemapQueued = false;
3458
+ });
3459
+ };
3460
+ /** Map source-indexed row definitions back onto the current virtual order. */
3461
+ this.reapplyRowDefinitionSizes = () => {
3462
+ const rowDefinitions = this.providers.dimension.getRowDefinitions();
3463
+ for (const rowType of column_service.rowTypes) {
3301
3464
  const items = this.providers.data.stores[rowType].store.get('items');
3465
+ const definitions = new Map(rowDefinitions
3466
+ .filter(definition => definition.type === rowType)
3467
+ .map(definition => [definition.index, definition.size]));
3468
+ const appliedIndexes = this.appliedDefinitionIndexes.get(rowType);
3469
+ if (!definitions.size && !(appliedIndexes === null || appliedIndexes === void 0 ? void 0 : appliedIndexes.size)) {
3470
+ continue;
3471
+ }
3472
+ const dimension = this.providers.dimension.stores[rowType];
3473
+ const currentSizes = dimension.store.get('sizes');
3474
+ const sizes = Object.assign({}, currentSizes);
3475
+ for (const index of appliedIndexes || []) {
3476
+ delete sizes[index];
3477
+ }
3302
3478
  const indexes = new Set();
3303
3479
  items.forEach((physicalIndex, virtualIndex) => {
3304
- if (committed.has(physicalIndex)) {
3480
+ const size = definitions.get(physicalIndex);
3481
+ if (size !== undefined) {
3482
+ sizes[virtualIndex] = size;
3305
3483
  indexes.add(virtualIndex);
3306
3484
  }
3307
3485
  });
3308
- this.appliedIndexes.set(rowType, indexes);
3486
+ this.appliedDefinitionIndexes.set(rowType, indexes);
3487
+ const sizeKeys = Object.keys(sizes);
3488
+ if (sizeKeys.length !== Object.keys(currentSizes).length ||
3489
+ sizeKeys.some(index => sizes[index] !== currentSizes[index])) {
3490
+ this.providers.dimension.setCustomSizes(rowType, sizes);
3491
+ }
3309
3492
  }
3310
3493
  };
3311
3494
  this.config = resolveRowResizeConfig(config);
3312
- this.rowDefinitionsRef = revogrid.rowDefinitions;
3313
3495
  if (new.target !== RowResizePlugin) {
3314
3496
  this.enabled = true;
3315
3497
  this.registerEventListeners();
@@ -3317,77 +3499,53 @@ class RowResizePlugin extends BasePlugin {
3317
3499
  }
3318
3500
  registerEventListeners() {
3319
3501
  this.addEventListener('beforerowrender', this.decorateRow);
3320
- this.addEventListener('beforeanysource', ({ detail }) => {
3502
+ this.addEventListener('beforeanysource', () => {
3321
3503
  this.cancel('data-change');
3322
- const committed = this.committedSizes.get(detail.type);
3323
- if (!committed) {
3324
- return;
3325
- }
3326
- const removedIndexes = new Set();
3327
- for (const index of committed.keys()) {
3328
- if (index >= detail.source.length) {
3329
- committed.delete(index);
3330
- removedIndexes.add(index);
3331
- }
3332
- }
3333
- if (removedIndexes.size) {
3334
- const rowDefinitions = this.revogrid.rowDefinitions.filter(definition => definition.type !== detail.type ||
3335
- !removedIndexes.has(definition.index));
3336
- this.rowDefinitionsRef = rowDefinitions;
3337
- this.revogrid.rowDefinitions = rowDefinitions;
3338
- }
3504
+ this.keepBottomAnchor = false;
3505
+ });
3506
+ this.addEventListener('afteranysource', ({ detail }) => {
3507
+ this.pendingSourceCounts.set(detail.type, detail.source.length);
3508
+ this.scheduleRowDefinitionRemap();
3339
3509
  });
3340
- this.addEventListener('afteranysource', this.rebuildCommittedSizes);
3341
3510
  this.addEventListener('beforesourcesortingapply', this.cancelForDataChange);
3342
- this.addEventListener('aftersortingapply', this.reapplyCommittedSizes);
3511
+ this.addEventListener('beforesortingapply', this.cancelForDataChange);
3512
+ this.addEventListener('sortingconfigchanged', this.cancelForDataChange);
3513
+ this.addEventListener(column_service.BEFORE_GROUPING_APPLY_EVENT, this.cancelForDataChange);
3514
+ this.addEventListener('aftersortingapply', this.scheduleRowDefinitionRemap);
3343
3515
  this.addEventListener('beforefilterapply', this.cancelForDataChange);
3344
- this.addEventListener('beforerowdefinition', ({ detail }) => {
3516
+ this.addEventListener('afterfilterapply', this.scheduleRowDefinitionRemap);
3517
+ this.addEventListener('beforerowdefinition', () => {
3345
3518
  this.cancel('data-change');
3346
- if (detail.vals !== this.rowDefinitionsRef) {
3347
- this.committedSizes.clear();
3348
- this.appliedIndexes.clear();
3349
- this.rowDefinitionsRef = detail.vals;
3350
- }
3351
- });
3352
- this.addEventListener('afterthemechanged', this.reapplyCommittedSizes);
3353
- this.addEventListener('aftertrimmed', this.syncAppliedIndexes);
3354
- this.addEventListener('roworderchange', () => {
3355
- queueMicrotask(this.reapplyCommittedSizes);
3519
+ this.scheduleRowDefinitionRemap();
3356
3520
  });
3521
+ this.addEventListener('afterthemechanged', this.scheduleRowDefinitionRemap);
3522
+ this.addEventListener('aftertrimmed', this.scheduleRowDefinitionRemap);
3523
+ this.addEventListener('roworderchange', this.scheduleRowDefinitionRemap);
3357
3524
  this.addEventListener(column_service.GROUP_EXPAND_EVENT, () => {
3358
- queueMicrotask(this.reapplyCommittedSizes);
3525
+ if (this.keepBottomAnchor) {
3526
+ this.pendingBottomAnchor = true;
3527
+ }
3528
+ this.scheduleRowDefinitionRemap();
3359
3529
  });
3530
+ this.addEventListener('aftergridrender', this.applyPendingBottomAnchor);
3531
+ this.addEventListener('viewportscroll', this.updateBottomAnchorState);
3360
3532
  this.addEventListener('rowheaderschanged', ({ detail }) => {
3361
3533
  if (!detail && !this.config.fullRow) {
3362
3534
  this.cancel('row-headers-hidden');
3363
3535
  }
3364
3536
  });
3365
3537
  }
3366
- controlFromGridProperty() {
3367
- this.gridResizeRow = this.revogrid.resizeRow;
3368
- this.gridPlugins = this.revogrid.plugins;
3369
- this.syncGridProperty(false);
3370
- this.watch('resizeRow', value => {
3371
- this.gridResizeRow = value;
3372
- this.syncGridProperty();
3373
- });
3374
- this.watch('plugins', value => {
3375
- this.gridPlugins = value || [];
3376
- this.syncGridProperty();
3377
- });
3378
- }
3379
- syncGridProperty(refresh = true) {
3380
- const hasConfiguredPlugin = this.gridPlugins.some(plugin => plugin !== RowResizePlugin &&
3538
+ syncGridConfig(refresh = true) {
3539
+ const { plugins = [], resizeRow } = this.revogrid;
3540
+ const isCorePlugin = this.constructor === RowResizePlugin;
3541
+ const hasConfiguredPlugin = plugins.some(plugin => plugin !== RowResizePlugin &&
3381
3542
  plugin.prototype instanceof RowResizePlugin);
3382
- const explicitlyEnabled = this.gridPlugins.includes(RowResizePlugin);
3383
- const enabled = hasConfiguredPlugin
3384
- ? false
3385
- : explicitlyEnabled || !!this.gridResizeRow;
3386
- const config = resolveRowResizeConfig(!hasConfiguredPlugin &&
3387
- !explicitlyEnabled &&
3388
- typeof this.gridResizeRow === 'object'
3389
- ? this.gridResizeRow
3390
- : undefined);
3543
+ const enabled = !isCorePlugin ||
3544
+ (!hasConfiguredPlugin && !!resizeRow);
3545
+ const resizeConfig = typeof resizeRow === 'object' ? resizeRow : undefined;
3546
+ const config = isCorePlugin
3547
+ ? resolveRowResizeConfig(resizeConfig)
3548
+ : this.config;
3391
3549
  const configChanged = config.minHeight !== this.config.minHeight ||
3392
3550
  config.maxHeight !== this.config.maxHeight ||
3393
3551
  config.fullRow !== this.config.fullRow;
@@ -3399,10 +3557,13 @@ class RowResizePlugin extends BasePlugin {
3399
3557
  if (enabled !== this.enabled) {
3400
3558
  this.enabled = enabled;
3401
3559
  if (enabled) {
3402
- this.rowDefinitionsRef = this.revogrid.rowDefinitions;
3403
3560
  this.registerEventListeners();
3404
3561
  }
3405
3562
  else {
3563
+ this.pendingBottomAnchor = false;
3564
+ this.keepBottomAnchor = false;
3565
+ this.rowDefinitionRemapQueued = false;
3566
+ this.pendingSourceCounts.clear();
3406
3567
  this.clearSubscriptions();
3407
3568
  }
3408
3569
  }
@@ -3421,6 +3582,7 @@ class RowResizePlugin extends BasePlugin {
3421
3582
  }
3422
3583
  const dimension = this.providers.dimension.stores[rowType];
3423
3584
  const dimensionState = dimension.getCurrentState();
3585
+ const viewport = this.providers.viewport.stores[rowType];
3424
3586
  const item = dimension_helpers.getItemByIndex(dimensionState, index);
3425
3587
  const focusedStore = this.providers.selection.focusedStore;
3426
3588
  const selectedRowType = focusedStore
@@ -3452,16 +3614,23 @@ class RowResizePlugin extends BasePlugin {
3452
3614
  currentHeight: startHeight,
3453
3615
  previousSizes,
3454
3616
  originalCustomSizes: Object.assign({}, dimensionState.sizes),
3455
- startEvent: event,
3617
+ bottomAnchored: rowType === 'rgRow' &&
3618
+ this.isMainViewportAtBottom(viewport.lastCoordinate),
3456
3619
  lastEvent: event,
3457
3620
  };
3621
+ this.active = active;
3458
3622
  const beforeEvent = this.emit(BEFORE_ROW_RESIZE_EVENT, this.eventDetail(active, event, startHeight));
3459
3623
  if (beforeEvent.defaultPrevented) {
3624
+ if (this.active === active) {
3625
+ this.active = undefined;
3626
+ }
3627
+ return;
3628
+ }
3629
+ if (!this.enabled || this.active !== active) {
3460
3630
  return;
3461
3631
  }
3462
3632
  event.preventDefault();
3463
3633
  event.stopPropagation();
3464
- this.active = active;
3465
3634
  const doc = this.revogrid.ownerDocument;
3466
3635
  this.previousBodyCursor = ((_a = doc.body) === null || _a === void 0 ? void 0 : _a.style.cursor) || '';
3467
3636
  if (doc.body) {
@@ -3484,6 +3653,7 @@ class RowResizePlugin extends BasePlugin {
3484
3653
  return;
3485
3654
  }
3486
3655
  this.providers.dimension.setCustomSizes(active.rowType, createRowResizePatch(active.indexes, size), true);
3656
+ this.requestBottomAnchor(active);
3487
3657
  active.currentHeight = size;
3488
3658
  this.emit(ROW_RESIZE_EVENT, this.eventDetail(active, active.lastEvent, size));
3489
3659
  }
@@ -3502,7 +3672,8 @@ class RowResizePlugin extends BasePlugin {
3502
3672
  }
3503
3673
  }
3504
3674
  this.providers.dimension.setCustomSizes(active.rowType, currentSizes);
3505
- const detail = Object.assign(Object.assign({}, this.eventDetail(active, active.lastEvent || active.startEvent, active.startHeight)), { reason });
3675
+ this.requestBottomAnchor(active);
3676
+ const detail = Object.assign(Object.assign({}, this.eventDetail(active, active.lastEvent, active.startHeight)), { reason });
3506
3677
  this.finishGesture();
3507
3678
  this.emit(ROW_RESIZE_CANCEL_EVENT, detail);
3508
3679
  }
@@ -3521,51 +3692,44 @@ class RowResizePlugin extends BasePlugin {
3521
3692
  return;
3522
3693
  }
3523
3694
  const items = this.providers.data.stores[active.rowType].store.get('items');
3524
- let committed = this.committedSizes.get(active.rowType);
3525
- if (!committed) {
3526
- committed = new Map();
3527
- this.committedSizes.set(active.rowType, committed);
3528
- }
3529
- let applied = this.appliedIndexes.get(active.rowType);
3530
- if (!applied) {
3531
- applied = new Set();
3532
- this.appliedIndexes.set(active.rowType, applied);
3533
- }
3534
3695
  const physicalIndexes = active.indexes.reduce((result, index) => {
3535
3696
  const physicalIndex = items[index];
3536
3697
  if (physicalIndex !== undefined) {
3537
- committed.set(physicalIndex, active.currentHeight);
3538
- applied.add(index);
3539
3698
  result.push(physicalIndex);
3540
3699
  }
3541
3700
  return result;
3542
3701
  }, []);
3543
3702
  if (physicalIndexes.length) {
3544
- const rowDefinitions = mergeRowResizeDefinitions(this.revogrid.rowDefinitions, active.rowType, physicalIndexes, active.currentHeight);
3545
- this.rowDefinitionsRef = rowDefinitions;
3546
- this.revogrid.rowDefinitions = rowDefinitions;
3703
+ const rowDefinitions = mergeRowResizeDefinitions(this.providers.dimension.getRowDefinitions(), active.rowType, physicalIndexes, active.currentHeight);
3704
+ this.providers.dimension.setRowDefinitions(rowDefinitions);
3705
+ this.scheduleRowDefinitionRemap();
3706
+ this.keepBottomAnchor = active.bottomAnchored;
3707
+ this.requestBottomAnchor(active);
3547
3708
  }
3548
3709
  }
3549
- applyCommittedSizes(clearAppliedIndexes) {
3550
- for (const [rowType, committed] of this.committedSizes) {
3551
- const dimension = this.providers.dimension.stores[rowType];
3552
- const sizes = Object.assign({}, dimension.store.get('sizes'));
3553
- if (clearAppliedIndexes) {
3554
- for (const index of this.appliedIndexes.get(rowType) || []) {
3555
- delete sizes[index];
3556
- }
3557
- }
3558
- const items = this.providers.data.stores[rowType].store.get('items');
3559
- const indexes = new Set();
3560
- items.forEach((physicalIndex, virtualIndex) => {
3561
- const size = committed.get(physicalIndex);
3562
- if (size !== undefined) {
3563
- sizes[virtualIndex] = size;
3564
- indexes.add(virtualIndex);
3565
- }
3566
- });
3567
- this.appliedIndexes.set(rowType, indexes);
3568
- this.providers.dimension.setCustomSizes(rowType, sizes);
3710
+ requestBottomAnchor(active) {
3711
+ if (active.bottomAnchored) {
3712
+ this.pendingBottomAnchor = true;
3713
+ }
3714
+ }
3715
+ isMainViewportAtBottom(coordinate) {
3716
+ const dimension = this.providers.dimension.stores.rgRow.getCurrentState();
3717
+ const viewport = this.providers.viewport.stores.rgRow.store.state;
3718
+ return (dimension.realSize > viewport.clientSize &&
3719
+ coordinate >= viewport_store.getViewportMaxCoordinate(dimension, viewport.virtualSize));
3720
+ }
3721
+ pruneRowDefinitions() {
3722
+ if (!this.pendingSourceCounts.size) {
3723
+ return;
3724
+ }
3725
+ const definitions = this.providers.dimension.getRowDefinitions();
3726
+ const rowDefinitions = definitions.filter(definition => {
3727
+ const count = this.pendingSourceCounts.get(definition.type);
3728
+ return count === undefined || definition.index < count;
3729
+ });
3730
+ this.pendingSourceCounts.clear();
3731
+ if (rowDefinitions.length !== definitions.length) {
3732
+ this.providers.dimension.setRowDefinitions(rowDefinitions);
3569
3733
  }
3570
3734
  }
3571
3735
  finishGesture() {
@@ -3588,6 +3752,9 @@ class RowResizePlugin extends BasePlugin {
3588
3752
  }
3589
3753
  destroy() {
3590
3754
  this.cancel('destroy');
3755
+ this.keepBottomAnchor = false;
3756
+ this.rowDefinitionRemapQueued = false;
3757
+ this.pendingSourceCounts.clear();
3591
3758
  super.destroy();
3592
3759
  }
3593
3760
  }
@@ -3627,6 +3794,7 @@ exports.doCollapse = doCollapse;
3627
3794
  exports.doExpand = doExpand;
3628
3795
  exports.filterCoreFunctionsIndexedByType = filterCoreFunctionsIndexedByType;
3629
3796
  exports.filterNames = filterNames;
3797
+ exports.filterTypeDefaults = filterTypeDefaults;
3630
3798
  exports.filterTypes = filterTypes;
3631
3799
  exports.getColumnDragPosition = getColumnDragPosition;
3632
3800
  exports.getComparer = getComparer;