@revolist/revogrid 4.23.3 → 4.23.5

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 (37) hide show
  1. package/dist/cjs/{column.drag.plugin-DJueWxN_.js → column.drag.plugin-yUSx3qoN.js} +2 -2
  2. package/dist/cjs/{header-cell-renderer-QrcXXSkF.js → header-cell-renderer-vVr4IWNV.js} +7 -18
  3. package/dist/cjs/index.cjs.js +3 -3
  4. package/dist/cjs/revo-grid.cjs.entry.js +13 -4
  5. package/dist/cjs/revogr-attribution_7.cjs.entry.js +1 -1
  6. package/dist/cjs/revogr-data_4.cjs.entry.js +27 -13
  7. package/dist/cjs/{viewport.store-BlKQ4x9H.js → viewport.store-BscUCiUk.js} +23 -0
  8. package/dist/collection/components/header/header-renderer.js +10 -7
  9. package/dist/collection/components/header/resizable.element.js +7 -18
  10. package/dist/collection/components/revoGrid/viewport.resize.service.js +1 -0
  11. package/dist/collection/components/scroll/revogr-viewport-scroll.js +15 -5
  12. package/dist/collection/services/dimension.provider.js +11 -2
  13. package/dist/collection/store/vp/viewport.helpers.js +23 -0
  14. package/dist/{revo-grid/column.drag.plugin-DCZW62Uc.js → esm/column.drag.plugin-Cg2U-91C.js} +2 -2
  15. package/dist/esm/{header-cell-renderer-BsvUQ8GS.js → header-cell-renderer-B-LX2sgu.js} +7 -18
  16. package/dist/esm/index.js +4 -4
  17. package/dist/esm/revo-grid.entry.js +13 -4
  18. package/dist/esm/revogr-attribution_7.entry.js +1 -1
  19. package/dist/esm/revogr-data_4.entry.js +27 -13
  20. package/dist/{revo-grid/viewport.store-COAfzAyu.js → esm/viewport.store-_c579YyM.js} +23 -0
  21. package/dist/{esm/column.drag.plugin-DCZW62Uc.js → revo-grid/column.drag.plugin-Cg2U-91C.js} +2 -2
  22. package/dist/revo-grid/{header-cell-renderer-BsvUQ8GS.js → header-cell-renderer-B-LX2sgu.js} +7 -18
  23. package/dist/revo-grid/index.esm.js +4 -4
  24. package/dist/revo-grid/revo-grid.entry.js +13 -4
  25. package/dist/revo-grid/revogr-attribution_7.entry.js +1 -1
  26. package/dist/revo-grid/revogr-data_4.entry.js +27 -13
  27. package/dist/{esm/viewport.store-COAfzAyu.js → revo-grid/viewport.store-_c579YyM.js} +23 -0
  28. package/dist/types/components/scroll/revogr-viewport-scroll.d.ts +1 -0
  29. package/dist/types/services/scroll.dimension.helpers.d.ts +19 -0
  30. package/dist/types/store/vp/viewport.helpers.d.ts +23 -0
  31. package/hydrate/index.js +66 -31
  32. package/hydrate/index.mjs +66 -31
  33. package/package.json +1 -1
  34. package/readme.md +127 -16
  35. package/standalone/revo-grid.js +1 -1
  36. package/standalone/revogr-header2.js +1 -1
  37. package/standalone/revogr-viewport-scroll2.js +1 -1
@@ -6,7 +6,7 @@ import { M as ColumnService, u as isGrouping } from './column.service-CC_SD8W3.j
6
6
  import { B as ROW_FOCUSED_CLASS, b as getSourceItem, n as DATA_ROW, m as DATA_COL, M as MIN_COL_SIZE, r as HEADER_SORTABLE_CLASS, H as HEADER_CLASS, F as FOCUS_CLASS, k as getItemByIndex, u as HEADER_ROW_CLASS, v as HEADER_ACTUAL_ROW_CLASS } from './dimension.helpers-CGKwSvw6.js';
7
7
  import { G as GroupingRowRenderer, C as CellRenderer, R as RowRenderer, P as PADDING_DEPTH, S as SortingSign } from './cell-renderer-BtN-NGCk.js';
8
8
  import { c as FilterButton } from './filter.button-C8XTWPU2.js';
9
- import { H as HeaderCellRenderer } from './header-cell-renderer-BsvUQ8GS.js';
9
+ import { H as HeaderCellRenderer } from './header-cell-renderer-B-LX2sgu.js';
10
10
  import { t as throttle, L as LocalScrollTimer, a as LocalScrollService, g as getContentSize } from './throttle-CaUDyxyU.js';
11
11
  import { H as HEADER_SLOT, C as CONTENT_SLOT, F as FOOTER_SLOT } from './viewport.helpers-CoCAvmZs.js';
12
12
  import './debounce-PCRWZliA.js';
@@ -262,20 +262,23 @@ const RevogrData = class {
262
262
  RevogrData.style = revogrDataStyleCss();
263
263
 
264
264
  const HeaderRenderer = (p) => {
265
- var _a, _b, _c, _d, _e, _f, _g;
265
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
266
+ const hasSortingSign = !!(((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable) ||
267
+ ((_b = p.data) === null || _b === void 0 ? void 0 : _b.order) ||
268
+ ((_c = p.data) === null || _c === void 0 ? void 0 : _c.sortIndex));
266
269
  const cellClass = {
267
270
  [HEADER_CLASS]: true,
268
- [HEADER_SORTABLE_CLASS]: !!((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable),
271
+ [HEADER_SORTABLE_CLASS]: !!((_d = p.data) === null || _d === void 0 ? void 0 : _d.sortable),
269
272
  };
270
- if ((_b = p.data) === null || _b === void 0 ? void 0 : _b.order) {
273
+ if ((_e = p.data) === null || _e === void 0 ? void 0 : _e.order) {
271
274
  cellClass[p.data.order] = true;
272
275
  }
273
276
  const dataProps = {
274
- key: String((_d = (_c = p.data) === null || _c === void 0 ? void 0 : _c.prop) !== null && _d !== void 0 ? _d : p.column.itemIndex),
277
+ key: String((_g = (_f = p.data) === null || _f === void 0 ? void 0 : _f.prop) !== null && _g !== void 0 ? _g : p.column.itemIndex),
275
278
  [DATA_COL]: p.column.itemIndex,
276
279
  canResize: p.canResize,
277
- minWidth: ((_e = p.data) === null || _e === void 0 ? void 0 : _e.minSize) || MIN_COL_SIZE,
278
- maxWidth: (_f = p.data) === null || _f === void 0 ? void 0 : _f.maxSize,
280
+ minWidth: ((_h = p.data) === null || _h === void 0 ? void 0 : _h.minSize) || MIN_COL_SIZE,
281
+ maxWidth: (_j = p.data) === null || _j === void 0 ? void 0 : _j.maxSize,
279
282
  active: p.active || ['r'],
280
283
  class: cellClass,
281
284
  style: {
@@ -311,7 +314,7 @@ const HeaderRenderer = (p) => {
311
314
  }
312
315
  }
313
316
  }
314
- return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, h(SortingSign, { column: p.data }), p.canFilter && ((_g = p.data) === null || _g === void 0 ? void 0 : _g.filter) !== false ? (h(FilterButton, { column: p.data })) : ('')));
317
+ return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, hasSortingSign ? h(SortingSign, { column: p.data }) : null, p.canFilter && ((_k = p.data) === null || _k === void 0 ? void 0 : _k.filter) !== false ? (h(FilterButton, { column: p.data })) : ('')));
315
318
  };
316
319
 
317
320
  const HeaderGroupRenderer = (p) => {
@@ -605,6 +608,7 @@ class GridResizeService {
605
608
  }
606
609
  destroy() {
607
610
  var _a;
611
+ this.apply.cancel();
608
612
  (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
609
613
  this.resizeObserver = null;
610
614
  }
@@ -743,6 +747,10 @@ const RevogrViewportScroll = class {
743
747
  scroll: this.horizontalScroll.scrollLeft,
744
748
  noScroll: this.colType !== 'rgCol',
745
749
  };
750
+ this.setScrollParams({
751
+ rgRow: calculatedHeight,
752
+ rgCol: calculatedWidth,
753
+ });
746
754
  // Process changes in order: width first, then height
747
755
  const dimensions = ['rgCol', 'rgRow'];
748
756
  for (const dimension of dimensions) {
@@ -799,24 +807,30 @@ const RevogrViewportScroll = class {
799
807
  }
800
808
  async componentDidRender() {
801
809
  var _a, _b, _c, _d;
810
+ this.setScrollParams({
811
+ rgRow: (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0,
812
+ rgCol: this.horizontalScroll.clientWidth,
813
+ });
814
+ this.setScrollVisibility('rgRow', (_d = (_c = this.verticalScroll) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : 0, this.contentHeight);
815
+ this.setScrollVisibility('rgCol', this.horizontalScroll.clientWidth, this.contentWidth);
816
+ }
817
+ setScrollParams(clientSize) {
802
818
  this.localScrollService.setParams({
803
819
  contentSize: this.contentHeight,
804
- clientSize: (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0,
820
+ clientSize: clientSize.rgRow,
805
821
  virtualSize: 0,
806
822
  }, 'rgRow');
807
823
  this.localScrollService.setParams({
808
824
  contentSize: this.contentWidth,
809
- clientSize: this.horizontalScroll.clientWidth,
825
+ clientSize: clientSize.rgCol,
810
826
  virtualSize: 0,
811
827
  }, 'rgCol');
812
- this.setScrollVisibility('rgRow', (_d = (_c = this.verticalScroll) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : 0, this.contentHeight);
813
- this.setScrollVisibility('rgCol', this.horizontalScroll.clientWidth, this.contentWidth);
814
828
  }
815
829
  render() {
816
830
  var _a, _b;
817
831
  const physicalContentHeight = getContentSize(this.contentHeight, (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0);
818
832
  const physicalContentWidth = getContentSize(this.contentWidth, 0);
819
- return (h(Host, { key: 'e52df53dcdcac76f02160615399c558e78fe5825', onWheel: this.horizontalMouseWheel, onScroll: (e) => this.applyScroll('rgCol', e) }, h("div", { key: '6821c4472db2208c2d52da9d6d43a7e5343d15bb', class: "inner-content-table", style: { width: `${physicalContentWidth}px` } }, h("div", { key: '1916ec94af312621ed4d937c905ed745a23a7d3b', class: "header-wrapper", ref: e => (this.header = e) }, h("slot", { key: '2348a566b127f27d969a4e2ff67fab4022501ceb', name: HEADER_SLOT })), h("div", { key: 'd88eebb7b0028b350f5b0feb6b3893efbd3f645c', class: "vertical-inner", ref: el => (this.verticalScroll = el), onWheel: this.verticalMouseWheel, onScroll: (e) => this.applyScroll('rgRow', e) }, h("div", { key: '1778856706d9d6bbc52882a150cb66c9b3f11e06', class: "content-wrapper", style: { height: `${physicalContentHeight}px` } }, h("slot", { key: '200bc8a9e692b6183ac2665b68961d28892f7cab', name: CONTENT_SLOT }))), h("div", { key: 'dc812739b4ad829867dd1effe94a871be247979a', class: "footer-wrapper", ref: e => (this.footer = e) }, h("slot", { key: '06e3b3a4f88c477dc33268ee317856820f2650e6', name: FOOTER_SLOT })))));
833
+ return (h(Host, { key: 'ec8d907976c1d50f7aab3c263be3f0249a274df6', onWheel: this.horizontalMouseWheel, onScroll: (e) => this.applyScroll('rgCol', e) }, h("div", { key: 'e35696a7993ac94261426b45c28d488cdc42b7f0', class: "inner-content-table", style: { width: `${physicalContentWidth}px` } }, h("div", { key: 'a6997451e01eacda1d27d4efa1d74e1748626218', class: "header-wrapper", ref: e => (this.header = e) }, h("slot", { key: '1d401e87d32d5b1531c2211723b552bbc894f22c', name: HEADER_SLOT })), h("div", { key: 'ceab6f9e812d6ca9a0aa376afcd2562a17f505e0', class: "vertical-inner", ref: el => (this.verticalScroll = el), onWheel: this.verticalMouseWheel, onScroll: (e) => this.applyScroll('rgRow', e) }, h("div", { key: 'a9556578a23d6efddec2e982e863aec064042154', class: "content-wrapper", style: { height: `${physicalContentHeight}px` } }, h("slot", { key: '0ae01f9736b9740612e75261f6e3abebda533377', name: CONTENT_SLOT }))), h("div", { key: '09c2565d4ed449a43820f92d97b6558fca3758e7', class: "footer-wrapper", ref: e => (this.footer = e) }, h("slot", { key: '1ffb08ff8138a560cc09d82e3fe22a53e502aafe', name: FOOTER_SLOT })))));
820
834
  }
821
835
  /**
822
836
  * Extra layer for scroll event monitoring, where MouseWheel event is not passing
@@ -15,6 +15,29 @@ function getViewportMaxCoordinate(dimension, viewportSize, frameOffset = 1) {
15
15
  }
16
16
  return Math.max(0, dimension.realSize - viewportSize - dimension.originItemSize * frameOffset);
17
17
  }
18
+ /**
19
+ * Clamp the viewport coordinate within the valid range.
20
+ * Given a scroll position, pick a safe starting point for rendering visible items.
21
+ *
22
+ * Do not use it when you need the exact scroll position for positioning math.
23
+ *
24
+ * It does two things:
25
+ * 1. If the coordinate is below 0, use 0.
26
+ * 2. If the coordinate is too close to the very end, pull it back a bit.
27
+ *
28
+ * Example:
29
+ *
30
+ * content height: 1000px
31
+ * viewport height: 200px
32
+ * row height: 30px
33
+ * The real max scroll is:
34
+ *
35
+ * 1000 - 200 = 800
36
+ * But clampViewportCoordinate may clamp to:
37
+ *
38
+ * 1000 - 200 - 30 = 770
39
+ * Ask for 800 -> it returns 770.
40
+ */
18
41
  function clampViewportCoordinate(coordinate, dimension, viewportSize, frameOffset = 1) {
19
42
  return Math.min(Math.max(0, coordinate), getViewportMaxCoordinate(dimension, viewportSize, frameOffset));
20
43
  }
@@ -3,12 +3,12 @@
3
3
  */
4
4
  import { J as reduce, g as getRange, K as baseEach, C as getColumnType, c as columnTypes, L as toInteger, u as isGrouping, t as getGroupingName, r as rowTypes, B as getCellDataParsed, A as getCellRaw, j as GROUP_COLUMN_PROP, I as getColumnByProp, h as GROUP_EXPANDED, x as getParsedGroup, y as isSameGroup, G as GROUP_DEPTH, e as PSEUDO_GROUP_ITEM_VALUE, d as PSEUDO_GROUP_ITEM_ID, o as GROUPING_ROW_TYPE, p as getSource, f as PSEUDO_GROUP_COLUMN, s as gatherGrouping, m as GROUP_EXPAND_EVENT, v as isGroupingColumn, q as getExpanded, E as isColGrouping } from './column.service-CC_SD8W3.js';
5
5
  import { K as createStore, l as setStore, i as calculateDimensionData, L as identity, N as isArray, b as getSourceItem, g as getPhysical, e as setItems, j as getItemByPosition } from './dimension.helpers-CGKwSvw6.js';
6
- import { j as calculateRowHeaderSize } from './viewport.store-COAfzAyu.js';
6
+ import { j as calculateRowHeaderSize } from './viewport.store-_c579YyM.js';
7
7
  import { g as getScrollbarSize, t as timeout } from './index-Db3qZoW5.js';
8
8
  import { h } from './index-Chp_81rd.js';
9
9
  import { b as FILTER_PROP, i as isFilterBtn } from './filter.button-C8XTWPU2.js';
10
10
  import { d as debounce } from './debounce-PCRWZliA.js';
11
- import { O as ON_COLUMN_CLICK, d as dispatch } from './header-cell-renderer-BsvUQ8GS.js';
11
+ import { O as ON_COLUMN_CLICK, d as dispatch } from './header-cell-renderer-B-LX2sgu.js';
12
12
 
13
13
  function calculateRealSize({ count, originItemSize, sizes, }) {
14
14
  const safeCount = Math.max(0, count);
@@ -283,24 +283,13 @@ const ResizableElement = (props, children) => {
283
283
  }
284
284
  })) ||
285
285
  null;
286
- if (props.active) {
287
- if (props.canResize) {
288
- for (let p in props.active) {
289
- resizeEls.push(h("div", { onClick: e => e.preventDefault(), onDblClick: e => {
290
- var _a;
291
- e.preventDefault();
292
- (_a = props.onDblClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
293
- }, onMouseDown: (e) => directive === null || directive === void 0 ? void 0 : directive.handleDown(e), onTouchStart: (e) => directive === null || directive === void 0 ? void 0 : directive.handleDown(e), class: `resizable resizable-${props.active[p]}` }));
294
- }
295
- }
296
- else {
297
- for (let _p in props.active) {
298
- resizeEls.push(h("div", { onClick: e => e.preventDefault(), onTouchStart: (e) => e.preventDefault(), onDblClick: e => {
299
- var _a;
300
- e.preventDefault();
301
- (_a = props.onDblClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
302
- }, class: `no-resize` }));
303
- }
286
+ if (props.active && props.canResize) {
287
+ for (let p in props.active) {
288
+ resizeEls.push(h("div", { onClick: e => e.preventDefault(), onDblClick: e => {
289
+ var _a;
290
+ e.preventDefault();
291
+ (_a = props.onDblClick) === null || _a === void 0 ? void 0 : _a.call(props, e);
292
+ }, onMouseDown: (e) => directive === null || directive === void 0 ? void 0 : directive.handleDown(e), onTouchStart: (e) => directive === null || directive === void 0 ? void 0 : directive.handleDown(e), class: `resizable resizable-${props.active[p]}` }));
304
293
  }
305
294
  }
306
295
  return (h("div", Object.assign({}, props, { ref: e => e && (directive === null || directive === void 0 ? void 0 : directive.set(e)) }), children, resizeEls));
@@ -2,16 +2,16 @@
2
2
  * Built by Revolist OU ❤️
3
3
  */
4
4
  export { o as GROUPING_ROW_TYPE, j as GROUP_COLUMN_PROP, G as GROUP_DEPTH, h as GROUP_EXPANDED, l as GROUP_EXPAND_BTN, m as GROUP_EXPAND_EVENT, k as GROUP_ORIGINAL_INDEX, f as PSEUDO_GROUP_COLUMN, P as PSEUDO_GROUP_ITEM, d as PSEUDO_GROUP_ITEM_ID, e as PSEUDO_GROUP_ITEM_VALUE, c as columnTypes, a as cropCellToMax, H as gatherGroup, s as gatherGrouping, z as getCellData, B as getCellDataParsed, A as getCellRaw, I as getColumnByProp, D as getColumnSizes, C as getColumnType, F as getColumns, q as getExpanded, t as getGroupingName, x as getParsedGroup, g as getRange, p as getSource, E as isColGrouping, u as isGrouping, v as isGroupingColumn, b as isRangeSingleCell, i as isRowType, y as isSameGroup, w as measureEqualDepth, n as nextCell, r as rowTypes } from './column.service-CC_SD8W3.js';
5
- import { B as BasePlugin } from './column.drag.plugin-DCZW62Uc.js';
6
- export { A as AutoSizeColumnPlugin, n as BEFORE_COLUMN_DRAG_END_EVENT, m as COLUMN_DRAG_END_EVENT, l as COLUMN_DRAG_MOVE_EVENT, o as COLUMN_DRAG_START_EVENT, C as ColumnAutoSizeMode, p as ColumnMovePlugin, D as DimensionStore, b as ExportCsv, E as ExportFilePlugin, c as FILTER_CONFIG_CHANGED_EVENT, F as FILTER_TRIMMED_TYPE, d as FILTE_PANEL, e as FilterPlugin, G as GroupingRowPlugin, S as SelectionStore, r as SortingPlugin, a as StretchColumn, v as defaultCellCompare, w as descCellCompare, j as doCollapse, k as doExpand, f as filterCoreFunctionsIndexedByType, h as filterNames, g as filterTypes, y as getComparer, q as getLeftRelative, x as getNextOrder, t as getSortingIndex, s as hasActiveSorting, i as isStretchPlugin, u as sortIndexByItems } from './column.drag.plugin-DCZW62Uc.js';
7
- export { d as dispatch, a as dispatchByEvent } from './header-cell-renderer-BsvUQ8GS.js';
5
+ import { B as BasePlugin } from './column.drag.plugin-Cg2U-91C.js';
6
+ export { A as AutoSizeColumnPlugin, n as BEFORE_COLUMN_DRAG_END_EVENT, m as COLUMN_DRAG_END_EVENT, l as COLUMN_DRAG_MOVE_EVENT, o as COLUMN_DRAG_START_EVENT, C as ColumnAutoSizeMode, p as ColumnMovePlugin, D as DimensionStore, b as ExportCsv, E as ExportFilePlugin, c as FILTER_CONFIG_CHANGED_EVENT, F as FILTER_TRIMMED_TYPE, d as FILTE_PANEL, e as FilterPlugin, G as GroupingRowPlugin, S as SelectionStore, r as SortingPlugin, a as StretchColumn, v as defaultCellCompare, w as descCellCompare, j as doCollapse, k as doExpand, f as filterCoreFunctionsIndexedByType, h as filterNames, g as filterTypes, y as getComparer, q as getLeftRelative, x as getNextOrder, t as getSortingIndex, s as hasActiveSorting, i as isStretchPlugin, u as sortIndexByItems } from './column.drag.plugin-Cg2U-91C.js';
7
+ export { d as dispatch, a as dispatchByEvent } from './header-cell-renderer-B-LX2sgu.js';
8
8
  export { C as CellRenderer, G as GroupingRowRenderer, S as SortingSign, e as expandEvent, a as expandSvgIconVNode } from './cell-renderer-BtN-NGCk.js';
9
9
  export { a as applyMixins, f as findPositionInArray, g as getScrollbarSize, m as mergeSortedArray, p as pushSorted, r as range, s as scaleValue, t as timeout } from './index-Db3qZoW5.js';
10
10
  export { T as TextEditor } from './text-editor-C3RUSwH5.js';
11
11
  export { k as isAll, c as isClear, h as isCopy, a as isCtrlKey, b as isCtrlMetaKey, g as isCut, m as isEditInput, n as isEditorCtrConstructible, f as isEnterKeyValue, i as isMetaKey, j as isPaste, l as isShortcutModifier, d as isTab, e as isTabKeyValue } from './edit.utils-Dnnbd0xG.js';
12
12
  export { h } from './index-Chp_81rd.js';
13
13
  export { C as CELL_CLASS, z as CELL_HANDLER_CLASS, m as DATA_COL, n as DATA_ROW, o as DISABLED_CLASS, x as DRAGGABLE_CLASS, A as DRAGG_TEXT, w as DRAG_ICON_CLASS, D as DataStore, E as EDIT_INPUT_WR, F as FOCUS_CLASS, G as GRID_INTERNALS, v as HEADER_ACTUAL_ROW_CLASS, H as HEADER_CLASS, u as HEADER_ROW_CLASS, r as HEADER_SORTABLE_CLASS, M as MIN_COL_SIZE, y as MOBILE_CLASS, R as RESIZE_INTERVAL, B as ROW_FOCUSED_CLASS, q as ROW_HEADER_TYPE, S as SELECTION_BORDER_CLASS, T as TMP_SELECTION_BG_CLASS, i as calculateDimensionData, I as codesLetter, h as gatherTrimmedItems, k as getItemByIndex, j as getItemByPosition, g as getPhysical, b as getSourceItem, f as getSourceItemVirtualIndexByProp, c as getSourcePhysicalIndex, a as getVisibleSourceItem, J as keyValues, p as proxyPlugin, e as setItems, d as setSourceByPhysicalIndex, s as setSourceByVirtualIndex, l as setStore, t as trimmedPlugin } from './dimension.helpers-CGKwSvw6.js';
14
- export { V as ViewportStore, b as addMissingItems, j as calculateRowHeaderSize, c as clampViewportCoordinate, f as getFirstItem, d as getItems, h as getLastItem, a as getUpdatedItemsByPosition, g as getViewportMaxCoordinate, i as isActiveRange, e as isActiveRangeOutsideLastItem, r as recombineByOffset, s as setItemSizes, u as updateMissingAndRange } from './viewport.store-COAfzAyu.js';
14
+ export { V as ViewportStore, b as addMissingItems, j as calculateRowHeaderSize, c as clampViewportCoordinate, f as getFirstItem, d as getItems, h as getLastItem, a as getUpdatedItemsByPosition, g as getViewportMaxCoordinate, i as isActiveRange, e as isActiveRangeOutsideLastItem, r as recombineByOffset, s as setItemSizes, u as updateMissingAndRange } from './viewport.store-_c579YyM.js';
15
15
  export { A as AND_OR_BUTTON, e as AndOrButton, a as FILTER_BUTTON_ACTIVE, F as FILTER_BUTTON_CLASS, b as FILTER_PROP, c as FilterButton, T as TRASH_BUTTON, d as TrashButton, i as isFilterBtn } from './filter.button-C8XTWPU2.js';
16
16
  import './debounce-PCRWZliA.js';
17
17
 
@@ -6,13 +6,13 @@ import { c as columnTypes, J as reduce, C as getColumnType, r as rowTypes, i as
6
6
  import { D as DataStore, b as getSourceItem, f as getSourceItemVirtualIndexByProp, d as setSourceByPhysicalIndex, s as setSourceByVirtualIndex, a as getVisibleSourceItem, h as gatherTrimmedItems, k as getItemByIndex, R as RESIZE_INTERVAL } from './dimension.helpers-CGKwSvw6.js';
7
7
  import { d as debounce } from './debounce-PCRWZliA.js';
8
8
  import { g as getScrollDimension, v as viewportDataPartition, F as FOOTER_SLOT, C as CONTENT_SLOT, H as HEADER_SLOT, D as DATA_SLOT } from './viewport.helpers-CoCAvmZs.js';
9
- import { c as clampViewportCoordinate, V as ViewportStore } from './viewport.store-COAfzAyu.js';
10
- import { D as DimensionStore, S as SelectionStore, B as BasePlugin, G as GroupingRowPlugin, a as StretchColumn, i as isStretchPlugin, A as AutoSizeColumnPlugin, e as FilterPlugin, E as ExportFilePlugin, r as SortingPlugin, p as ColumnMovePlugin } from './column.drag.plugin-DCZW62Uc.js';
9
+ import { D as DimensionStore, S as SelectionStore, B as BasePlugin, G as GroupingRowPlugin, a as StretchColumn, i as isStretchPlugin, A as AutoSizeColumnPlugin, e as FilterPlugin, E as ExportFilePlugin, r as SortingPlugin, p as ColumnMovePlugin } from './column.drag.plugin-Cg2U-91C.js';
10
+ import { V as ViewportStore } from './viewport.store-_c579YyM.js';
11
11
  import { T as ThemeService } from './theme.service-BmnDvr6P.js';
12
12
  import { t as timeout } from './index-Db3qZoW5.js';
13
13
  import { g as getPropertyFromEvent } from './events-BvSmBueA.js';
14
14
  import './filter.button-C8XTWPU2.js';
15
- import './header-cell-renderer-BsvUQ8GS.js';
15
+ import './header-cell-renderer-B-LX2sgu.js';
16
16
 
17
17
  class ColumnDataProvider {
18
18
  get stores() {
@@ -372,7 +372,16 @@ class DimensionProvider {
372
372
  clientSize,
373
373
  virtualSize: viewportSize,
374
374
  });
375
- const renderCoordinate = clampViewportCoordinate(coordinate, dimension, viewportSize);
375
+ // Render offset must use the true logical scroll coordinate
376
+ // It is the logical scroll position that should be used for compressed-scroll offset math.
377
+ const renderCoordinate = Math.min(Math.max(0, coordinate), // prevents negative scroll positions
378
+ scrollDimension.logicalScrollSize); // prevents positions past the logical end
379
+ /**
380
+ * If viewport sizing is initialized (clientSize and viewportSize are truthy), calculate the offset needed for compressed scroll.
381
+ * Otherwise keep renderOffset at 0, because there is not enough measurement data yet.
382
+ *
383
+ * In normal scrolling, logical and physical coordinates are the same, so offset is 0.
384
+ */
376
385
  const renderOffset = clientSize && viewportSize
377
386
  ? scrollDimension.getRenderOffset(renderCoordinate)
378
387
  : 0;
@@ -8,7 +8,7 @@ import { g as getRange, M as ColumnService, z as getCellData, N as getCellEditor
8
8
  import { l as isShortcutModifier, m as isEditInput, c as isClear, d as isTab, f as isEnterKeyValue, h as isCopy, g as isCut, j as isPaste, k as isAll } from './edit.utils-Dnnbd0xG.js';
9
9
  import { t as timeout, g as getScrollbarSize } from './index-Db3qZoW5.js';
10
10
  import { d as debounce } from './debounce-PCRWZliA.js';
11
- import { V as ViewportStore, j as calculateRowHeaderSize } from './viewport.store-COAfzAyu.js';
11
+ import { V as ViewportStore, j as calculateRowHeaderSize } from './viewport.store-_c579YyM.js';
12
12
  import { H as HEADER_SLOT } from './viewport.helpers-CoCAvmZs.js';
13
13
  import { L as LocalScrollTimer, a as LocalScrollService, g as getContentSize, t as throttle } from './throttle-CaUDyxyU.js';
14
14
 
@@ -6,7 +6,7 @@ import { M as ColumnService, u as isGrouping } from './column.service-CC_SD8W3.j
6
6
  import { B as ROW_FOCUSED_CLASS, b as getSourceItem, n as DATA_ROW, m as DATA_COL, M as MIN_COL_SIZE, r as HEADER_SORTABLE_CLASS, H as HEADER_CLASS, F as FOCUS_CLASS, k as getItemByIndex, u as HEADER_ROW_CLASS, v as HEADER_ACTUAL_ROW_CLASS } from './dimension.helpers-CGKwSvw6.js';
7
7
  import { G as GroupingRowRenderer, C as CellRenderer, R as RowRenderer, P as PADDING_DEPTH, S as SortingSign } from './cell-renderer-BtN-NGCk.js';
8
8
  import { c as FilterButton } from './filter.button-C8XTWPU2.js';
9
- import { H as HeaderCellRenderer } from './header-cell-renderer-BsvUQ8GS.js';
9
+ import { H as HeaderCellRenderer } from './header-cell-renderer-B-LX2sgu.js';
10
10
  import { t as throttle, L as LocalScrollTimer, a as LocalScrollService, g as getContentSize } from './throttle-CaUDyxyU.js';
11
11
  import { H as HEADER_SLOT, C as CONTENT_SLOT, F as FOOTER_SLOT } from './viewport.helpers-CoCAvmZs.js';
12
12
  import './debounce-PCRWZliA.js';
@@ -262,20 +262,23 @@ const RevogrData = class {
262
262
  RevogrData.style = revogrDataStyleCss();
263
263
 
264
264
  const HeaderRenderer = (p) => {
265
- var _a, _b, _c, _d, _e, _f, _g;
265
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
266
+ const hasSortingSign = !!(((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable) ||
267
+ ((_b = p.data) === null || _b === void 0 ? void 0 : _b.order) ||
268
+ ((_c = p.data) === null || _c === void 0 ? void 0 : _c.sortIndex));
266
269
  const cellClass = {
267
270
  [HEADER_CLASS]: true,
268
- [HEADER_SORTABLE_CLASS]: !!((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable),
271
+ [HEADER_SORTABLE_CLASS]: !!((_d = p.data) === null || _d === void 0 ? void 0 : _d.sortable),
269
272
  };
270
- if ((_b = p.data) === null || _b === void 0 ? void 0 : _b.order) {
273
+ if ((_e = p.data) === null || _e === void 0 ? void 0 : _e.order) {
271
274
  cellClass[p.data.order] = true;
272
275
  }
273
276
  const dataProps = {
274
- key: String((_d = (_c = p.data) === null || _c === void 0 ? void 0 : _c.prop) !== null && _d !== void 0 ? _d : p.column.itemIndex),
277
+ key: String((_g = (_f = p.data) === null || _f === void 0 ? void 0 : _f.prop) !== null && _g !== void 0 ? _g : p.column.itemIndex),
275
278
  [DATA_COL]: p.column.itemIndex,
276
279
  canResize: p.canResize,
277
- minWidth: ((_e = p.data) === null || _e === void 0 ? void 0 : _e.minSize) || MIN_COL_SIZE,
278
- maxWidth: (_f = p.data) === null || _f === void 0 ? void 0 : _f.maxSize,
280
+ minWidth: ((_h = p.data) === null || _h === void 0 ? void 0 : _h.minSize) || MIN_COL_SIZE,
281
+ maxWidth: (_j = p.data) === null || _j === void 0 ? void 0 : _j.maxSize,
279
282
  active: p.active || ['r'],
280
283
  class: cellClass,
281
284
  style: {
@@ -311,7 +314,7 @@ const HeaderRenderer = (p) => {
311
314
  }
312
315
  }
313
316
  }
314
- return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, h(SortingSign, { column: p.data }), p.canFilter && ((_g = p.data) === null || _g === void 0 ? void 0 : _g.filter) !== false ? (h(FilterButton, { column: p.data })) : ('')));
317
+ return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, hasSortingSign ? h(SortingSign, { column: p.data }) : null, p.canFilter && ((_k = p.data) === null || _k === void 0 ? void 0 : _k.filter) !== false ? (h(FilterButton, { column: p.data })) : ('')));
315
318
  };
316
319
 
317
320
  const HeaderGroupRenderer = (p) => {
@@ -605,6 +608,7 @@ class GridResizeService {
605
608
  }
606
609
  destroy() {
607
610
  var _a;
611
+ this.apply.cancel();
608
612
  (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
609
613
  this.resizeObserver = null;
610
614
  }
@@ -743,6 +747,10 @@ const RevogrViewportScroll = class {
743
747
  scroll: this.horizontalScroll.scrollLeft,
744
748
  noScroll: this.colType !== 'rgCol',
745
749
  };
750
+ this.setScrollParams({
751
+ rgRow: calculatedHeight,
752
+ rgCol: calculatedWidth,
753
+ });
746
754
  // Process changes in order: width first, then height
747
755
  const dimensions = ['rgCol', 'rgRow'];
748
756
  for (const dimension of dimensions) {
@@ -799,24 +807,30 @@ const RevogrViewportScroll = class {
799
807
  }
800
808
  async componentDidRender() {
801
809
  var _a, _b, _c, _d;
810
+ this.setScrollParams({
811
+ rgRow: (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0,
812
+ rgCol: this.horizontalScroll.clientWidth,
813
+ });
814
+ this.setScrollVisibility('rgRow', (_d = (_c = this.verticalScroll) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : 0, this.contentHeight);
815
+ this.setScrollVisibility('rgCol', this.horizontalScroll.clientWidth, this.contentWidth);
816
+ }
817
+ setScrollParams(clientSize) {
802
818
  this.localScrollService.setParams({
803
819
  contentSize: this.contentHeight,
804
- clientSize: (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0,
820
+ clientSize: clientSize.rgRow,
805
821
  virtualSize: 0,
806
822
  }, 'rgRow');
807
823
  this.localScrollService.setParams({
808
824
  contentSize: this.contentWidth,
809
- clientSize: this.horizontalScroll.clientWidth,
825
+ clientSize: clientSize.rgCol,
810
826
  virtualSize: 0,
811
827
  }, 'rgCol');
812
- this.setScrollVisibility('rgRow', (_d = (_c = this.verticalScroll) === null || _c === void 0 ? void 0 : _c.clientHeight) !== null && _d !== void 0 ? _d : 0, this.contentHeight);
813
- this.setScrollVisibility('rgCol', this.horizontalScroll.clientWidth, this.contentWidth);
814
828
  }
815
829
  render() {
816
830
  var _a, _b;
817
831
  const physicalContentHeight = getContentSize(this.contentHeight, (_b = (_a = this.verticalScroll) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0);
818
832
  const physicalContentWidth = getContentSize(this.contentWidth, 0);
819
- return (h(Host, { key: 'e52df53dcdcac76f02160615399c558e78fe5825', onWheel: this.horizontalMouseWheel, onScroll: (e) => this.applyScroll('rgCol', e) }, h("div", { key: '6821c4472db2208c2d52da9d6d43a7e5343d15bb', class: "inner-content-table", style: { width: `${physicalContentWidth}px` } }, h("div", { key: '1916ec94af312621ed4d937c905ed745a23a7d3b', class: "header-wrapper", ref: e => (this.header = e) }, h("slot", { key: '2348a566b127f27d969a4e2ff67fab4022501ceb', name: HEADER_SLOT })), h("div", { key: 'd88eebb7b0028b350f5b0feb6b3893efbd3f645c', class: "vertical-inner", ref: el => (this.verticalScroll = el), onWheel: this.verticalMouseWheel, onScroll: (e) => this.applyScroll('rgRow', e) }, h("div", { key: '1778856706d9d6bbc52882a150cb66c9b3f11e06', class: "content-wrapper", style: { height: `${physicalContentHeight}px` } }, h("slot", { key: '200bc8a9e692b6183ac2665b68961d28892f7cab', name: CONTENT_SLOT }))), h("div", { key: 'dc812739b4ad829867dd1effe94a871be247979a', class: "footer-wrapper", ref: e => (this.footer = e) }, h("slot", { key: '06e3b3a4f88c477dc33268ee317856820f2650e6', name: FOOTER_SLOT })))));
833
+ return (h(Host, { key: 'ec8d907976c1d50f7aab3c263be3f0249a274df6', onWheel: this.horizontalMouseWheel, onScroll: (e) => this.applyScroll('rgCol', e) }, h("div", { key: 'e35696a7993ac94261426b45c28d488cdc42b7f0', class: "inner-content-table", style: { width: `${physicalContentWidth}px` } }, h("div", { key: 'a6997451e01eacda1d27d4efa1d74e1748626218', class: "header-wrapper", ref: e => (this.header = e) }, h("slot", { key: '1d401e87d32d5b1531c2211723b552bbc894f22c', name: HEADER_SLOT })), h("div", { key: 'ceab6f9e812d6ca9a0aa376afcd2562a17f505e0', class: "vertical-inner", ref: el => (this.verticalScroll = el), onWheel: this.verticalMouseWheel, onScroll: (e) => this.applyScroll('rgRow', e) }, h("div", { key: 'a9556578a23d6efddec2e982e863aec064042154', class: "content-wrapper", style: { height: `${physicalContentHeight}px` } }, h("slot", { key: '0ae01f9736b9740612e75261f6e3abebda533377', name: CONTENT_SLOT }))), h("div", { key: '09c2565d4ed449a43820f92d97b6558fca3758e7', class: "footer-wrapper", ref: e => (this.footer = e) }, h("slot", { key: '1ffb08ff8138a560cc09d82e3fe22a53e502aafe', name: FOOTER_SLOT })))));
820
834
  }
821
835
  /**
822
836
  * Extra layer for scroll event monitoring, where MouseWheel event is not passing
@@ -15,6 +15,29 @@ function getViewportMaxCoordinate(dimension, viewportSize, frameOffset = 1) {
15
15
  }
16
16
  return Math.max(0, dimension.realSize - viewportSize - dimension.originItemSize * frameOffset);
17
17
  }
18
+ /**
19
+ * Clamp the viewport coordinate within the valid range.
20
+ * Given a scroll position, pick a safe starting point for rendering visible items.
21
+ *
22
+ * Do not use it when you need the exact scroll position for positioning math.
23
+ *
24
+ * It does two things:
25
+ * 1. If the coordinate is below 0, use 0.
26
+ * 2. If the coordinate is too close to the very end, pull it back a bit.
27
+ *
28
+ * Example:
29
+ *
30
+ * content height: 1000px
31
+ * viewport height: 200px
32
+ * row height: 30px
33
+ * The real max scroll is:
34
+ *
35
+ * 1000 - 200 = 800
36
+ * But clampViewportCoordinate may clamp to:
37
+ *
38
+ * 1000 - 200 - 30 = 770
39
+ * Ask for 800 -> it returns 770.
40
+ */
18
41
  function clampViewportCoordinate(coordinate, dimension, viewportSize, frameOffset = 1) {
19
42
  return Math.min(Math.max(0, coordinate), getViewportMaxCoordinate(dimension, viewportSize, frameOffset));
20
43
  }
@@ -90,6 +90,7 @@ export declare class RevogrViewportScroll implements ElementScroll {
90
90
  setScrollVisibility(type: DimensionType, size: number, innerContentSize: number): void;
91
91
  disconnectedCallback(): void;
92
92
  componentDidRender(): Promise<void>;
93
+ private setScrollParams;
93
94
  render(): any;
94
95
  /**
95
96
  * Extra layer for scroll event monitoring, where MouseWheel event is not passing
@@ -5,11 +5,30 @@ export type ScrollDimensionInput = {
5
5
  maxScrollSize?: number;
6
6
  };
7
7
  export type ScrollDimension = {
8
+ /**
9
+ * Real logical grid content size
10
+ * e.g. 1_000_000 rows * 46px = 46_000_000px.
11
+ */
8
12
  contentSize: number;
13
+ /**
14
+ * Visible viewport size provided by the browser
15
+ * e.g. 600px height of the scrollable container.
16
+ */
9
17
  clientSize: number;
10
18
  viewportSize: number;
19
+ /**
20
+ * Fake DOM scrollable size that RevoGrid gives the browser scrollbar.
21
+ * Grid maps between physical scrollbar coordinates and logical grid coordinates so rows still represent the full dataset.
22
+ */
11
23
  physicalContentSize: number;
24
+ /**
25
+ * How far the grid should be scrollable logically.
26
+ * contentSize - viewportSize, meaning the largest valid logical scroll coordinate.
27
+ */
12
28
  logicalScrollSize: number;
29
+ /**
30
+ * How far the browser scrollbar can actually move.
31
+ */
13
32
  physicalScrollSize: number;
14
33
  isCompressed: boolean;
15
34
  toLogicalCoordinate(coordinate: number): number;
@@ -2,6 +2,29 @@ import type { DimensionSettingsState, PositionItem, ViewSettingSizeProp, Viewpor
2
2
  export type DimensionDataViewport = Pick<DimensionSettingsState, 'indexes' | 'positionIndexes' | 'positionIndexToItem' | 'sizes' | 'originItemSize' | 'realSize'>;
3
3
  export type ItemsToUpdate = Pick<ViewportStateItems, 'items' | 'start' | 'end'>;
4
4
  export declare function getViewportMaxCoordinate(dimension: Pick<DimensionSettingsState, 'realSize' | 'originItemSize'>, viewportSize: number, frameOffset?: number): number;
5
+ /**
6
+ * Clamp the viewport coordinate within the valid range.
7
+ * Given a scroll position, pick a safe starting point for rendering visible items.
8
+ *
9
+ * Do not use it when you need the exact scroll position for positioning math.
10
+ *
11
+ * It does two things:
12
+ * 1. If the coordinate is below 0, use 0.
13
+ * 2. If the coordinate is too close to the very end, pull it back a bit.
14
+ *
15
+ * Example:
16
+ *
17
+ * content height: 1000px
18
+ * viewport height: 200px
19
+ * row height: 30px
20
+ * The real max scroll is:
21
+ *
22
+ * 1000 - 200 = 800
23
+ * But clampViewportCoordinate may clamp to:
24
+ *
25
+ * 1000 - 200 - 30 = 770
26
+ * Ask for 800 -> it returns 770.
27
+ */
5
28
  export declare function clampViewportCoordinate(coordinate: number, dimension: Pick<DimensionSettingsState, 'realSize' | 'originItemSize'>, viewportSize: number, frameOffset?: number): number;
6
29
  /**
7
30
  * Update items based on new scroll position