beautiful-grid 1.0.4 → 1.0.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.
@@ -163,12 +163,13 @@ var LazyGridOptionalSurfaces = React.lazy(function () {
163
163
  }); });
164
164
  });
165
165
  function Table(props) {
166
+ var _a;
166
167
  var _this = this;
167
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5;
168
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
168
169
  var cellSelectionOptions = props.cellSelectionOptions, onChangeData = props.onChangeData, sourceIndexByVisibleIndex = props.sourceIndexByVisibleIndex;
169
- var cellSelectionEnabled = (_a = cellSelectionOptions === null || cellSelectionOptions === void 0 ? void 0 : cellSelectionOptions.enabled) !== null && _a !== void 0 ? _a : true;
170
+ var cellSelectionEnabled = (_b = cellSelectionOptions === null || cellSelectionOptions === void 0 ? void 0 : cellSelectionOptions.enabled) !== null && _b !== void 0 ? _b : true;
170
171
  // [Selector Group 1] Layout & Dimensions - 레이아웃 차원
171
- var _6 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
172
+ var _7 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
172
173
  width: s.width,
173
174
  height: s.height,
174
175
  containerBorderWidth: s.containerBorderWidth,
@@ -176,30 +177,30 @@ function Table(props) {
176
177
  style: s.style,
177
178
  itemHeight: s.itemHeight,
178
179
  itemPadding: s.itemPadding,
179
- }); })), width = _6.width, height = _6.height, containerBorderWidth = _6.containerBorderWidth, className = _6.className, style = _6.style, itemHeight = _6.itemHeight, itemPadding = _6.itemPadding;
180
+ }); })), width = _7.width, height = _7.height, containerBorderWidth = _7.containerBorderWidth, className = _7.className, style = _7.style, itemHeight = _7.itemHeight, itemPadding = _7.itemPadding;
180
181
  // [Selector Group 2] Header, Footer, Summary - 헤더/푸터/요약
181
- var _7 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
182
+ var _8 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
182
183
  headerHeight: s.headerHeight,
183
184
  footerHeight: s.footerHeight,
184
185
  bottomBarHeight: s.bottomBarHeight,
185
186
  summaryHeight: s.summaryHeight,
186
- }); })), headerHeight = _7.headerHeight, footerHeight = _7.footerHeight, bottomBarHeight = _7.bottomBarHeight, summaryHeight = _7.summaryHeight;
187
+ }); })), headerHeight = _8.headerHeight, footerHeight = _8.footerHeight, bottomBarHeight = _8.bottomBarHeight, summaryHeight = _8.summaryHeight;
187
188
  // [Selector Group 3] Scroll State - 스크롤 상태
188
- var _8 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
189
+ var _9 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
189
190
  scrollLeft: s.scrollLeft,
190
191
  scrollTop: s.scrollTop,
191
- }); })), scrollLeft = _8.scrollLeft, scrollTop = _8.scrollTop;
192
+ }); })), scrollLeft = _9.scrollLeft, scrollTop = _9.scrollTop;
192
193
  // [Selector Group 4] Content, Columns, Data - 컨텐츠 관련
193
- var _9 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
194
+ var _10 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
194
195
  contentBodyHeight: s.contentBodyHeight,
195
196
  columns: s.columns,
196
197
  data: s.data,
197
198
  frozenColumnsWidth: s.frozenColumnsWidth,
198
199
  frozenRowCount: s.frozenRowCount,
199
200
  frozenRowsHeight: s.frozenRowsHeight,
200
- }); })), contentBodyHeight = _9.contentBodyHeight, columns = _9.columns, data = _9.data, frozenColumnsWidth = _9.frozenColumnsWidth, frozenRowCount = _9.frozenRowCount, frozenRowsHeight = _9.frozenRowsHeight;
201
+ }); })), contentBodyHeight = _10.contentBodyHeight, columns = _10.columns, data = _10.data, frozenColumnsWidth = _10.frozenColumnsWidth, frozenRowCount = _10.frozenRowCount, frozenRowsHeight = _10.frozenRowsHeight;
201
202
  // [Selector Group 4-1] Cell selection & navigation - 셀 선택 및 내비게이션
202
- var _10 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
203
+ var _11 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
203
204
  cellSelectionRange: s.cellSelectionRange,
204
205
  cellSelectionRanges: s.cellSelectionRanges,
205
206
  activeCell: s.activeCell,
@@ -208,9 +209,9 @@ function Table(props) {
208
209
  editItemIndex: s.editItemIndex,
209
210
  editable: s.editable,
210
211
  handleClick: s.handleClick,
211
- }); })), cellSelectionRange = _10.cellSelectionRange, cellSelectionRanges = _10.cellSelectionRanges, activeCell = _10.activeCell, activeCellHost = _10.activeCellHost, cellNavigationOptions = _10.cellNavigationOptions, editItemIndex = _10.editItemIndex, editable = _10.editable, handleClick = _10.handleClick;
212
+ }); })), cellSelectionRange = _11.cellSelectionRange, cellSelectionRanges = _11.cellSelectionRanges, activeCell = _11.activeCell, activeCellHost = _11.activeCellHost, cellNavigationOptions = _11.cellNavigationOptions, editItemIndex = _11.editItemIndex, editable = _11.editable, handleClick = _11.handleClick;
212
213
  // [Selector Group 5] State - 상태
213
- var _11 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
214
+ var _12 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
214
215
  rowChecked: s.rowChecked,
215
216
  page: s.page,
216
217
  loading: s.loading,
@@ -220,8 +221,8 @@ function Table(props) {
220
221
  scrollbar: s.scrollbar,
221
222
  status: s.status,
222
223
  pagination: s.pagination,
223
- }); })), rowChecked = _11.rowChecked, page = _11.page, loading = _11.loading, spinning = _11.spinning, showLineNumber = _11.showLineNumber, summary = _11.summary, scrollbar = _11.scrollbar, status = _11.status, pagination = _11.pagination;
224
- var _12 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
224
+ }); })), rowChecked = _12.rowChecked, page = _12.page, loading = _12.loading, spinning = _12.spinning, showLineNumber = _12.showLineNumber, summary = _12.summary, scrollbar = _12.scrollbar, status = _12.status, pagination = _12.pagination;
225
+ var _13 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
225
226
  searchOpen: s.searchOpen,
226
227
  searchOptions: s.searchOptions,
227
228
  contextMenuOptions: s.contextMenuOptions,
@@ -230,9 +231,9 @@ function Table(props) {
230
231
  storeSourceIndexByVisibleIndex: s.sourceIndexByVisibleIndex,
231
232
  storeRowKey: s.rowKey,
232
233
  cellInteractionSession: s.cellInteractionSession,
233
- }); })), searchOpen = _12.searchOpen, searchOptions = _12.searchOptions, contextMenuOptions = _12.contextMenuOptions, activeSearchMatchIndex = _12.activeSearchMatchIndex, searchMatches = _12.searchMatches, storeSourceIndexByVisibleIndex = _12.storeSourceIndexByVisibleIndex, storeRowKey = _12.storeRowKey, cellInteractionSession = _12.cellInteractionSession;
234
+ }); })), searchOpen = _13.searchOpen, searchOptions = _13.searchOptions, contextMenuOptions = _13.contextMenuOptions, activeSearchMatchIndex = _13.activeSearchMatchIndex, searchMatches = _13.searchMatches, storeSourceIndexByVisibleIndex = _13.storeSourceIndexByVisibleIndex, storeRowKey = _13.storeRowKey, cellInteractionSession = _13.cellInteractionSession;
234
235
  // [Selector Group 6] State Setters - 차원 설정자
235
- var _13 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
236
+ var _14 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
236
237
  setHeight: s.setHeight,
237
238
  setWidth: s.setWidth,
238
239
  setContentBodyHeight: s.setContentBodyHeight,
@@ -245,9 +246,9 @@ function Table(props) {
245
246
  setItemPadding: s.setItemPadding,
246
247
  setLoading: s.setLoading,
247
248
  setSpinning: s.setSpinning,
248
- }); })), setHeight = _13.setHeight, setWidth = _13.setWidth, setContentBodyHeight = _13.setContentBodyHeight, setDisplayItemCount = _13.setDisplayItemCount, setHeaderHeight = _13.setHeaderHeight, setFooterHeight = _13.setFooterHeight, setBottomBarHeight = _13.setBottomBarHeight, setSummaryHeight = _13.setSummaryHeight, setItemHeight = _13.setItemHeight, setItemPadding = _13.setItemPadding, setLoading = _13.setLoading, setSpinning = _13.setSpinning;
249
+ }); })), setHeight = _14.setHeight, setWidth = _14.setWidth, setContentBodyHeight = _14.setContentBodyHeight, setDisplayItemCount = _14.setDisplayItemCount, setHeaderHeight = _14.setHeaderHeight, setFooterHeight = _14.setFooterHeight, setBottomBarHeight = _14.setBottomBarHeight, setSummaryHeight = _14.setSummaryHeight, setItemHeight = _14.setItemHeight, setItemPadding = _14.setItemPadding, setLoading = _14.setLoading, setSpinning = _14.setSpinning;
249
250
  // [Selector Group 7] Data & Column Setters - 데이터/열 설정자
250
- var _14 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
251
+ var _15 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
251
252
  setData: s.setData,
252
253
  setSourceData: s.setSourceData,
253
254
  setProcessedData: s.setProcessedData,
@@ -258,9 +259,9 @@ function Table(props) {
258
259
  setFrozenColumnIndex: s.setFrozenColumnIndex,
259
260
  setFrozenRowCount: s.setFrozenRowCount,
260
261
  setFrozenRowsHeight: s.setFrozenRowsHeight,
261
- }); })), setData = _14.setData, setSourceData = _14.setSourceData, setProcessedData = _14.setProcessedData, setColumns = _14.setColumns, setColumnsGroup = _14.setColumnsGroup, setColumnGroups = _14.setColumnGroups, setFrozenColumnsWidth = _14.setFrozenColumnsWidth, setFrozenColumnIndex = _14.setFrozenColumnIndex, setFrozenRowCount = _14.setFrozenRowCount, setFrozenRowsHeight = _14.setFrozenRowsHeight;
262
+ }); })), setData = _15.setData, setSourceData = _15.setSourceData, setProcessedData = _15.setProcessedData, setColumns = _15.setColumns, setColumnsGroup = _15.setColumnsGroup, setColumnGroups = _15.setColumnGroups, setFrozenColumnsWidth = _15.setFrozenColumnsWidth, setFrozenColumnIndex = _15.setFrozenColumnIndex, setFrozenRowCount = _15.setFrozenRowCount, setFrozenRowsHeight = _15.setFrozenRowsHeight;
262
263
  // [Selector Group 8] Row & Sort Setters - 행/정렬 설정자
263
- var _15 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
264
+ var _16 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
264
265
  setRowChecked: s.setRowChecked,
265
266
  setCheckedIndexesMap: s.setCheckedIndexesMap,
266
267
  setSort: s.setSort,
@@ -277,9 +278,9 @@ function Table(props) {
277
278
  requestSearchOpen: s.requestSearchOpen,
278
279
  openContextMenu: s.openContextMenu,
279
280
  commitCheckboxCell: s.commitCheckboxCell,
280
- }); })), setRowChecked = _15.setRowChecked, setCheckedIndexesMap = _15.setCheckedIndexesMap, setSort = _15.setSort, setSortParams = _15.setSortParams, setDataQuery = _15.setDataQuery, setDataControl = _15.setDataControl, setIcons = _15.setIcons, setActiveToolbox = _15.setActiveToolbox, setRowKey = _15.setRowKey, setFocusedRowKey = _15.setFocusedRowKey, setEditItem = _15.setEditItem, setSearchOptions = _15.setSearchOptions, setContextMenuOptions = _15.setContextMenuOptions, requestSearchOpen = _15.requestSearchOpen, openContextMenu = _15.openContextMenu, commitCheckboxCell = _15.commitCheckboxCell;
281
+ }); })), setRowChecked = _16.setRowChecked, setCheckedIndexesMap = _16.setCheckedIndexesMap, setSort = _16.setSort, setSortParams = _16.setSortParams, setDataQuery = _16.setDataQuery, setDataControl = _16.setDataControl, setIcons = _16.setIcons, setActiveToolbox = _16.setActiveToolbox, setRowKey = _16.setRowKey, setFocusedRowKey = _16.setFocusedRowKey, setEditItem = _16.setEditItem, setSearchOptions = _16.setSearchOptions, setContextMenuOptions = _16.setContextMenuOptions, requestSearchOpen = _16.requestSearchOpen, openContextMenu = _16.openContextMenu, commitCheckboxCell = _16.commitCheckboxCell;
281
282
  // [Selector Group 9] Pagination & Display Setters - 페이지/표시 설정자
282
- var _16 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
283
+ var _17 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
283
284
  setPage: s.setPage,
284
285
  setDisplayPaginationLength: s.setDisplayPaginationLength,
285
286
  setShowLineNumber: s.setShowLineNumber,
@@ -295,9 +296,9 @@ function Table(props) {
295
296
  setScrollbar: s.setScrollbar,
296
297
  setStatus: s.setStatus,
297
298
  setPagination: s.setPagination,
298
- }); })), setPage = _16.setPage, setDisplayPaginationLength = _16.setDisplayPaginationLength, setShowLineNumber = _16.setShowLineNumber, setMsg = _16.setMsg, setRowClassName = _16.setRowClassName, setCellMergeOptions = _16.setCellMergeOptions, setVariant = _16.setVariant, setSummary = _16.setSummary, setColumnSortable = _16.setColumnSortable, setReorder = _16.setReorder, setClassName = _16.setClassName, setStyle = _16.setStyle, setScrollbar = _16.setScrollbar, setStatus = _16.setStatus, setPagination = _16.setPagination;
299
+ }); })), setPage = _17.setPage, setDisplayPaginationLength = _17.setDisplayPaginationLength, setShowLineNumber = _17.setShowLineNumber, setMsg = _17.setMsg, setRowClassName = _17.setRowClassName, setCellMergeOptions = _17.setCellMergeOptions, setVariant = _17.setVariant, setSummary = _17.setSummary, setColumnSortable = _17.setColumnSortable, setReorder = _17.setReorder, setClassName = _17.setClassName, setStyle = _17.setStyle, setScrollbar = _17.setScrollbar, setStatus = _17.setStatus, setPagination = _17.setPagination;
299
300
  // [Selector Group 10] Edit & Event Setters - 편집/이벤트 설정자
300
- var _17 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
301
+ var _18 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
301
302
  setEditable: s.setEditable,
302
303
  setEditTrigger: s.setEditTrigger,
303
304
  setOnClick: s.setOnClick,
@@ -306,8 +307,8 @@ function Table(props) {
306
307
  setOnLoadMore: s.setOnLoadMore,
307
308
  setScroll: s.setScroll,
308
309
  setInitialized: s.setInitialized,
309
- }); })), setEditable = _17.setEditable, setEditTrigger = _17.setEditTrigger, setOnClick = _17.setOnClick, setOnChangeColumns = _17.setOnChangeColumns, setOnChangeData = _17.setOnChangeData, setOnLoadMore = _17.setOnLoadMore, setScroll = _17.setScroll, setInitialized = _17.setInitialized;
310
- var _18 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
310
+ }); })), setEditable = _18.setEditable, setEditTrigger = _18.setEditTrigger, setOnClick = _18.setOnClick, setOnChangeColumns = _18.setOnChangeColumns, setOnChangeData = _18.setOnChangeData, setOnLoadMore = _18.setOnLoadMore, setScroll = _18.setScroll, setInitialized = _18.setInitialized;
311
+ var _19 = (0, store_1.useAppStore)((0, shallow_1.useShallow)(function (s) { return ({
311
312
  setCellSelectionRanges: s.setCellSelectionRanges,
312
313
  setCellSelecting: s.setCellSelecting,
313
314
  clearCellSelection: s.clearCellSelection,
@@ -315,9 +316,10 @@ function Table(props) {
315
316
  moveActiveCell: s.moveActiveCell,
316
317
  setCellNavigationOptions: s.setCellNavigationOptions,
317
318
  syncActiveCellToBounds: s.syncActiveCellToBounds,
318
- }); })), setCellSelectionRanges = _18.setCellSelectionRanges, setCellSelecting = _18.setCellSelecting, clearCellSelection = _18.clearCellSelection, setActiveCell = _18.setActiveCell, moveActiveCell = _18.moveActiveCell, setCellNavigationOptions = _18.setCellNavigationOptions, syncActiveCellToBounds = _18.syncActiveCellToBounds;
319
+ }); })), setCellSelectionRanges = _19.setCellSelectionRanges, setCellSelecting = _19.setCellSelecting, clearCellSelection = _19.clearCellSelection, setActiveCell = _19.setActiveCell, moveActiveCell = _19.moveActiveCell, setCellNavigationOptions = _19.setCellNavigationOptions, syncActiveCellToBounds = _19.syncActiveCellToBounds;
319
320
  var trHeight = itemHeight + itemPadding * 2;
320
321
  var scrollableBodyHeight = Math.max(contentBodyHeight - frozenRowsHeight, 0);
322
+ var scrollOverscanRows = Math.max(KEYBOARD_NAVIGATION_ROW_WINDOW_SIZE, Math.ceil(scrollableBodyHeight / Math.max(trHeight, 1)));
321
323
  var mainViewportWidth = Math.max(width - (frozenColumnsWidth !== null && frozenColumnsWidth !== void 0 ? frozenColumnsWidth : 0), 0);
322
324
  var logicalBodyContentHeight = data.length * trHeight;
323
325
  var virtualScrollWindowMetrics = React.useMemo(function () {
@@ -327,7 +329,7 @@ function Table(props) {
327
329
  enabled: scrollbar.variant !== 'native',
328
330
  });
329
331
  }, [contentBodyHeight, logicalBodyContentHeight, scrollbar.variant]);
330
- var _19 = __read(React.useState(0), 2), virtualScrollBase = _19[0], setVirtualScrollBase = _19[1];
332
+ var _20 = __read(React.useState(0), 2), virtualScrollBase = _20[0], setVirtualScrollBase = _20[1];
331
333
  var virtualScrollBaseRef = (0, react_1.useRef)(0);
332
334
  var containerRef = (0, react_1.useRef)(null);
333
335
  var searchPopoverRef = (0, react_1.useRef)(null);
@@ -337,7 +339,8 @@ function Table(props) {
337
339
  var logicalVerticalScrollState = React.useMemo(function () { return ({
338
340
  scrollTop: scrollTop,
339
341
  scrollHeight: virtualScrollWindowMetrics.logicalContentHeight,
340
- }); }, [scrollTop, virtualScrollWindowMetrics.logicalContentHeight]);
342
+ maxScrollTop: virtualScrollWindowMetrics.logicalMaxScroll,
343
+ }); }, [scrollTop, virtualScrollWindowMetrics.logicalContentHeight, virtualScrollWindowMetrics.logicalMaxScroll]);
341
344
  var hasMultiCellSelection = React.useMemo(function () {
342
345
  return cellSelectionRanges.length > 1 ||
343
346
  cellSelectionRanges.some(function (range) {
@@ -447,9 +450,11 @@ function Table(props) {
447
450
  rowHeight: trHeight,
448
451
  frozenRowCount: frozenRowCount,
449
452
  totalRowCount: data.length,
453
+ overscan: scrollOverscanRows,
454
+ leadingOverscan: scrollOverscanRows,
450
455
  windowSize: ((_a = props.reorder) === null || _a === void 0 ? void 0 : _a.enabled) ? 1 : KEYBOARD_NAVIGATION_ROW_WINDOW_SIZE,
451
456
  });
452
- }, [data.length, frozenRowCount, (_b = props.reorder) === null || _b === void 0 ? void 0 : _b.enabled, scrollTop, scrollableBodyHeight, trHeight]);
457
+ }, [data.length, frozenRowCount, (_c = props.reorder) === null || _c === void 0 ? void 0 : _c.enabled, scrollOverscanRows, scrollTop, scrollableBodyHeight, trHeight]);
453
458
  var frozenRowRange = React.useMemo(function () { return ({ startRowIndex: 0, endRowIndex: frozenRowCount }); }, [frozenRowCount]);
454
459
  var scrollableRowRange = React.useMemo(function () { return ({
455
460
  startRowIndex: visibleScrollableRows.startRowIndex,
@@ -619,7 +624,7 @@ function Table(props) {
619
624
  var latestCommittedScrollRef = (0, react_1.useRef)({ top: scrollTop, left: scrollLeft });
620
625
  var scrollPropsRef = (0, react_1.useRef)({ top: props.scrollTop, left: props.scrollLeft });
621
626
  var syncedDataPropRef = (0, react_1.useRef)(props.data);
622
- var _20 = __read(React.useState(null), 2), rowScrollRequest = _20[0], setRowScrollRequest = _20[1];
627
+ var _21 = __read(React.useState(null), 2), rowScrollRequest = _21[0], setRowScrollRequest = _21[1];
623
628
  React.useImperativeHandle(props.ref, function () { return ({
624
629
  scrollToRow: function (rowIndex, options) {
625
630
  var _a;
@@ -636,7 +641,7 @@ function Table(props) {
636
641
  var selectionMetricsRef = (0, react_1.useRef)({
637
642
  columns: columns,
638
643
  dataLength: data.length,
639
- frozenColumnIndex: (_c = props.frozenColumnIndex) !== null && _c !== void 0 ? _c : 0,
644
+ frozenColumnIndex: (_d = props.frozenColumnIndex) !== null && _d !== void 0 ? _d : 0,
640
645
  frozenRowCount: frozenRowCount,
641
646
  frozenColumnsWidth: frozenColumnsWidth !== null && frozenColumnsWidth !== void 0 ? frozenColumnsWidth : 0,
642
647
  frozenRowsHeight: frozenRowsHeight,
@@ -1498,7 +1503,7 @@ function Table(props) {
1498
1503
  setFrozenColumnIndex((_d = props.frozenColumnIndex) !== null && _d !== void 0 ? _d : 0);
1499
1504
  }, [
1500
1505
  props.frozenColumnIndex,
1501
- (_d = props.reorder) === null || _d === void 0 ? void 0 : _d.enabled,
1506
+ (_e = props.reorder) === null || _e === void 0 ? void 0 : _e.enabled,
1502
1507
  showLineNumber,
1503
1508
  rowChecked,
1504
1509
  itemHeight,
@@ -1514,7 +1519,7 @@ function Table(props) {
1514
1519
  var nextFrozenRowCount = Math.min(Math.max(Math.floor((_c = props.frozenRowCount) !== null && _c !== void 0 ? _c : 0), 0), rowCount);
1515
1520
  setFrozenRowCount(nextFrozenRowCount);
1516
1521
  setFrozenRowsHeight(nextFrozenRowCount * trHeight);
1517
- }, [data.length, (_e = props.data) === null || _e === void 0 ? void 0 : _e.length, props.frozenRowCount, setFrozenRowCount, setFrozenRowsHeight, trHeight]);
1522
+ }, [data.length, (_f = props.data) === null || _f === void 0 ? void 0 : _f.length, props.frozenRowCount, setFrozenRowCount, setFrozenRowsHeight, trHeight]);
1518
1523
  // [Group 5] Data & columns
1519
1524
  (0, react_1.useEffect)(function () {
1520
1525
  if (props.data !== undefined &&
@@ -1605,23 +1610,23 @@ function Table(props) {
1605
1610
  }
1606
1611
  }, [
1607
1612
  props.page,
1608
- (_f = props.page) === null || _f === void 0 ? void 0 : _f.currentPage,
1609
- (_g = props.page) === null || _g === void 0 ? void 0 : _g.loading,
1610
- (_h = props.page) === null || _h === void 0 ? void 0 : _h.pageSize,
1611
- (_j = props.page) === null || _j === void 0 ? void 0 : _j.totalPages,
1612
- (_k = props.page) === null || _k === void 0 ? void 0 : _k.totalElements,
1613
- (_l = props.page) === null || _l === void 0 ? void 0 : _l.onChange,
1614
- (_m = props.page) === null || _m === void 0 ? void 0 : _m.displayPaginationLength,
1613
+ (_g = props.page) === null || _g === void 0 ? void 0 : _g.currentPage,
1614
+ (_h = props.page) === null || _h === void 0 ? void 0 : _h.loading,
1615
+ (_j = props.page) === null || _j === void 0 ? void 0 : _j.pageSize,
1616
+ (_k = props.page) === null || _k === void 0 ? void 0 : _k.totalPages,
1617
+ (_l = props.page) === null || _l === void 0 ? void 0 : _l.totalElements,
1618
+ (_m = props.page) === null || _m === void 0 ? void 0 : _m.onChange,
1619
+ (_o = props.page) === null || _o === void 0 ? void 0 : _o.displayPaginationLength,
1615
1620
  setPage,
1616
1621
  setDisplayPaginationLength,
1617
1622
  ]);
1618
- var previousPageRef = (0, react_1.useRef)((_o = props.page) === null || _o === void 0 ? void 0 : _o.currentPage);
1623
+ var previousPageRef = (0, react_1.useRef)((_p = props.page) === null || _p === void 0 ? void 0 : _p.currentPage);
1619
1624
  (0, react_1.useEffect)(function () {
1620
1625
  var _a, _b;
1621
1626
  if (previousPageRef.current !== ((_a = props.page) === null || _a === void 0 ? void 0 : _a.currentPage))
1622
1627
  resetScrollPosition('top');
1623
1628
  previousPageRef.current = (_b = props.page) === null || _b === void 0 ? void 0 : _b.currentPage;
1624
- }, [resetScrollPosition, (_p = props.page) === null || _p === void 0 ? void 0 : _p.currentPage]);
1629
+ }, [resetScrollPosition, (_q = props.page) === null || _q === void 0 ? void 0 : _q.currentPage]);
1625
1630
  // [Group 8] Row key & selection
1626
1631
  (0, react_1.useEffect)(function () {
1627
1632
  setRowKey(props.rowKey);
@@ -1693,10 +1698,10 @@ function Table(props) {
1693
1698
  }, [
1694
1699
  columns.length,
1695
1700
  data.length,
1696
- (_r = (_q = props.cellNavigationOptions) === null || _q === void 0 ? void 0 : _q.activeCell) === null || _r === void 0 ? void 0 : _r.columnIndex,
1697
- (_t = (_s = props.cellNavigationOptions) === null || _s === void 0 ? void 0 : _s.activeCell) === null || _t === void 0 ? void 0 : _t.rowIndex,
1698
- (_v = (_u = props.cellNavigationOptions) === null || _u === void 0 ? void 0 : _u.defaultActiveCell) === null || _v === void 0 ? void 0 : _v.columnIndex,
1699
- (_x = (_w = props.cellNavigationOptions) === null || _w === void 0 ? void 0 : _w.defaultActiveCell) === null || _x === void 0 ? void 0 : _x.rowIndex,
1701
+ (_s = (_r = props.cellNavigationOptions) === null || _r === void 0 ? void 0 : _r.activeCell) === null || _s === void 0 ? void 0 : _s.columnIndex,
1702
+ (_u = (_t = props.cellNavigationOptions) === null || _t === void 0 ? void 0 : _t.activeCell) === null || _u === void 0 ? void 0 : _u.rowIndex,
1703
+ (_w = (_v = props.cellNavigationOptions) === null || _v === void 0 ? void 0 : _v.defaultActiveCell) === null || _w === void 0 ? void 0 : _w.columnIndex,
1704
+ (_y = (_x = props.cellNavigationOptions) === null || _x === void 0 ? void 0 : _x.defaultActiveCell) === null || _y === void 0 ? void 0 : _y.rowIndex,
1700
1705
  syncActiveCellToBounds,
1701
1706
  ]);
1702
1707
  // setInitialized + DOM event bindings
@@ -1818,8 +1823,8 @@ function Table(props) {
1818
1823
  endCellSelectionDrag();
1819
1824
  clearCellSelection();
1820
1825
  }, [cellSelectionEnabled, clearCellSelection, endCellSelectionDrag]);
1821
- var clearCellSelectionOnEscape = (_z = (_y = props.cellSelectionOptions) === null || _y === void 0 ? void 0 : _y.clearOnEscape) !== null && _z !== void 0 ? _z : true;
1822
- var clearCellSelectionOnOutsideClick = (_1 = (_0 = props.cellSelectionOptions) === null || _0 === void 0 ? void 0 : _0.clearOnOutsideClick) !== null && _1 !== void 0 ? _1 : true;
1826
+ var clearCellSelectionOnEscape = (_0 = (_z = props.cellSelectionOptions) === null || _z === void 0 ? void 0 : _z.clearOnEscape) !== null && _0 !== void 0 ? _0 : true;
1827
+ var clearCellSelectionOnOutsideClick = (_2 = (_1 = props.cellSelectionOptions) === null || _1 === void 0 ? void 0 : _1.clearOnOutsideClick) !== null && _2 !== void 0 ? _2 : true;
1823
1828
  var keyboardRuntimeRef = (0, react_1.useRef)({
1824
1829
  activeCell: activeCell,
1825
1830
  cellInteractionSession: cellInteractionSession,
@@ -1837,7 +1842,7 @@ function Table(props) {
1837
1842
  editable: editable,
1838
1843
  editItemIndex: editItemIndex,
1839
1844
  endCellSelectionDrag: endCellSelectionDrag,
1840
- frozenColumnIndex: (_2 = props.frozenColumnIndex) !== null && _2 !== void 0 ? _2 : 0,
1845
+ frozenColumnIndex: (_3 = props.frozenColumnIndex) !== null && _3 !== void 0 ? _3 : 0,
1841
1846
  frozenRowCount: frozenRowCount,
1842
1847
  height: height,
1843
1848
  handleClick: handleClick,
@@ -1870,7 +1875,7 @@ function Table(props) {
1870
1875
  editable: editable,
1871
1876
  editItemIndex: editItemIndex,
1872
1877
  endCellSelectionDrag: endCellSelectionDrag,
1873
- frozenColumnIndex: (_3 = props.frozenColumnIndex) !== null && _3 !== void 0 ? _3 : 0,
1878
+ frozenColumnIndex: (_4 = props.frozenColumnIndex) !== null && _4 !== void 0 ? _4 : 0,
1874
1879
  frozenRowCount: frozenRowCount,
1875
1880
  height: height,
1876
1881
  handleClick: handleClick,
@@ -2252,14 +2257,14 @@ function Table(props) {
2252
2257
  };
2253
2258
  }, []);
2254
2259
  return (React.createElement(EditorPortalRoot_1.EditorPortalContext.Provider, { value: editorPortalContext },
2255
- React.createElement(Container, { ref: containerRef, role: 'grid', style: __assign(__assign({}, style), { width: width, height: height, borderWidth: "".concat(containerBorderWidth, "px") }), className: className, tabIndex: 0, onFocus: function (event) {
2260
+ React.createElement(Container, { ref: containerRef, role: 'grid', style: __assign(__assign({}, style), (_a = { width: width, height: height, borderWidth: "".concat(containerBorderWidth, "px") }, _a['--bgrid-virtual-row-height'] = "".concat(trHeight, "px"), _a)), className: className, tabIndex: 0, onFocus: function (event) {
2256
2261
  if (event.target !== event.currentTarget)
2257
2262
  return;
2258
2263
  var gateway = event.currentTarget.querySelector('[data-bgrid-text-editor-gateway="true"]');
2259
2264
  if (gateway instanceof HTMLInputElement) {
2260
2265
  gateway.focus({ preventScroll: true });
2261
2266
  }
2262
- }, "data-scroll-variant": scrollbar.variant, "data-vertical-scrollbar": scrollbar.variant !== 'native' && scrollbar.vertical.visible ? 'visible' : 'hidden', "data-bgrid-cell-selection-enabled": cellSelectionEnabled ? 'true' : 'false', "data-bgrid-frozen-columns": ((_4 = props.frozenColumnIndex) !== null && _4 !== void 0 ? _4 : 0) > 0 ? 'true' : 'false' },
2267
+ }, "data-scroll-variant": scrollbar.variant, "data-vertical-scrollbar": scrollbar.variant !== 'native' && scrollbar.vertical.visible ? 'visible' : 'hidden', "data-bgrid-cell-selection-enabled": cellSelectionEnabled ? 'true' : 'false', "data-bgrid-frozen-columns": ((_5 = props.frozenColumnIndex) !== null && _5 !== void 0 ? _5 : 0) > 0 ? 'true' : 'false' },
2263
2268
  scrollbar.variant !== 'native' && scrollbar.vertical.visible && (React.createElement("div", { className: 'bgrid-vertical-scrollbar-gutter', "aria-hidden": 'true' })),
2264
2269
  scrollbar.variant !== 'native' && scrollbar.vertical.visible && (React.createElement("div", { className: 'bgrid-vertical-scrollbar-area', style: {
2265
2270
  top: 0,
@@ -2288,6 +2293,11 @@ function Table(props) {
2288
2293
  React.createElement(TableSummaryFronzen_1.TableSummaryFrozen, { position: 'top' }))),
2289
2294
  React.createElement(Summary, { style: { left: frozenColumnsWidth }, role: 'rfdg-summary' },
2290
2295
  React.createElement(TableSummary_1.TableSummary, { position: 'top' })))),
2296
+ React.createElement("div", { className: 'bgrid-virtual-row-backdrop', "aria-hidden": 'true', style: {
2297
+ top: stickyTopHeight,
2298
+ height: contentBodyHeight,
2299
+ marginBottom: -contentBodyHeight,
2300
+ } }),
2291
2301
  React.createElement("div", { className: 'bgrid-body-scroll-content', style: { height: virtualScrollWindowMetrics.physicalContentHeight } },
2292
2302
  frozenRowCount > 0 && (React.createElement("div", { className: 'bgrid-frozen-rows-layer', style: { height: frozenRowsHeight, top: stickyTopHeight }, "data-bgrid-row-band": 'frozen' },
2293
2303
  (frozenColumnsWidth !== null && frozenColumnsWidth !== void 0 ? frozenColumnsWidth : 0) > 0 && (React.createElement("div", { className: 'bgrid-frozen-rows-left bgrid-frozen-column-boundary', style: { width: frozenColumnsWidth }, role: 'rfdg-frozen-rows-left' },
@@ -2318,7 +2328,7 @@ function Table(props) {
2318
2328
  React.createElement(Summary, { style: { left: frozenColumnsWidth }, role: 'rfdg-summary' },
2319
2329
  React.createElement(TableSummary_1.TableSummary, { position: 'bottom' })))))),
2320
2330
  React.createElement(BodyViewport, { ref: bodyContainerRef, style: { top: stickyTopHeight, height: contentBodyHeight }, "data-last": !page ? 'true' : undefined },
2321
- ((_5 = rowReorderController.preview) === null || _5 === void 0 ? void 0 : _5.visible) && (React.createElement("div", { className: 'bgrid-row-reorder-preview', "data-bgrid-row-reorder-phase": rowReorderController.preview.phase, "aria-hidden": 'true' }, rowReorderController.preview.text)),
2331
+ ((_6 = rowReorderController.preview) === null || _6 === void 0 ? void 0 : _6.visible) && (React.createElement("div", { className: 'bgrid-row-reorder-preview', "data-bgrid-row-reorder-phase": rowReorderController.preview.phase, "aria-hidden": 'true' }, rowReorderController.preview.text)),
2322
2332
  React.createElement(Loading_1.default, { active: !!spinning, size: 'small' })),
2323
2333
  React.createElement("div", { className: 'bgrid-visually-hidden', role: 'status', "aria-live": 'polite', "aria-atomic": 'true' }, rowReorderController.announcement),
2324
2334
  React.createElement(CellTextEditorGateway_1.CellTextEditorGateway, { containerRef: containerRef }),
@@ -53,8 +53,8 @@ function getRowBottom(rowIndex, rowHeight) {
53
53
  return (rowIndex + 1) * rowHeight;
54
54
  }
55
55
  function ensureCellVisible(_a) {
56
- var _b, _c, _d, _e, _f, _g, _h, _j;
57
- var cell = _a.cell, scrollContainer = _a.scrollContainer, _k = _a.frozenColumnCount, frozenColumnCount = _k === void 0 ? 0 : _k, _l = _a.frozenRowCount, frozenRowCount = _l === void 0 ? 0 : _l, columns = _a.columns, rowHeight = _a.rowHeight, verticalScrollState = _a.verticalScrollState, viewportInsets = _a.viewportInsets;
56
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k;
57
+ var cell = _a.cell, scrollContainer = _a.scrollContainer, _l = _a.frozenColumnCount, frozenColumnCount = _l === void 0 ? 0 : _l, _m = _a.frozenRowCount, frozenRowCount = _m === void 0 ? 0 : _m, columns = _a.columns, rowHeight = _a.rowHeight, verticalScrollState = _a.verticalScrollState, viewportInsets = _a.viewportInsets;
58
58
  var currentScrollTop = (_c = (_b = verticalScrollState === null || verticalScrollState === void 0 ? void 0 : verticalScrollState.scrollTop) !== null && _b !== void 0 ? _b : scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollTop) !== null && _c !== void 0 ? _c : 0;
59
59
  var currentScrollLeft = (_d = scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.scrollLeft) !== null && _d !== void 0 ? _d : 0;
60
60
  var nextScrollTop = currentScrollTop;
@@ -66,10 +66,10 @@ function ensureCellVisible(_a) {
66
66
  var rowBottom = getRowBottom(targetRowIndex, rowHeight);
67
67
  var clientHeight = scrollContainer.clientHeight;
68
68
  var scrollHeight = (_e = verticalScrollState === null || verticalScrollState === void 0 ? void 0 : verticalScrollState.scrollHeight) !== null && _e !== void 0 ? _e : scrollContainer.scrollHeight;
69
- var maxScrollTop = Math.max(0, scrollHeight - clientHeight);
69
+ var maxScrollTop = Math.max(0, (_f = verticalScrollState === null || verticalScrollState === void 0 ? void 0 : verticalScrollState.maxScrollTop) !== null && _f !== void 0 ? _f : scrollHeight - clientHeight);
70
70
  if (clientHeight > 0) {
71
- var topInset = clamp((_f = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.top) !== null && _f !== void 0 ? _f : 0, 0, clientHeight);
72
- var bottomInset = clamp((_g = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.bottom) !== null && _g !== void 0 ? _g : 0, 0, Math.max(clientHeight - topInset, 0));
71
+ var topInset = clamp((_g = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.top) !== null && _g !== void 0 ? _g : 0, 0, clientHeight);
72
+ var bottomInset = clamp((_h = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.bottom) !== null && _h !== void 0 ? _h : 0, 0, Math.max(clientHeight - topInset, 0));
73
73
  var viewportTop = currentScrollTop + topInset;
74
74
  var viewportBottom = currentScrollTop + clientHeight - bottomInset;
75
75
  if (rowTop < viewportTop) {
@@ -90,8 +90,8 @@ function ensureCellVisible(_a) {
90
90
  var scrollWidth = scrollContainer.scrollWidth;
91
91
  var maxScrollLeft = Math.max(0, scrollWidth - clientWidth);
92
92
  if (clientWidth > 0) {
93
- var leftInset = clamp((_h = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.left) !== null && _h !== void 0 ? _h : 0, 0, clientWidth);
94
- var rightInset = clamp((_j = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.right) !== null && _j !== void 0 ? _j : 0, 0, Math.max(clientWidth - leftInset, 0));
93
+ var leftInset = clamp((_j = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.left) !== null && _j !== void 0 ? _j : 0, 0, clientWidth);
94
+ var rightInset = clamp((_k = viewportInsets === null || viewportInsets === void 0 ? void 0 : viewportInsets.right) !== null && _k !== void 0 ? _k : 0, 0, Math.max(clientWidth - leftInset, 0));
95
95
  var viewportLeft = currentScrollLeft + leftInset;
96
96
  var viewportRight = currentScrollLeft + clientWidth - rightInset;
97
97
  var visibleWidth = Math.max(clientWidth - leftInset - rightInset, 0);
@@ -6,7 +6,7 @@ exports.getVisibleScrollableRowRange = getVisibleScrollableRowRange;
6
6
  * The returned end index is exclusive.
7
7
  */
8
8
  function getVisibleScrollableRowRange(_a) {
9
- var scrollTop = _a.scrollTop, viewportHeight = _a.viewportHeight, rowHeight = _a.rowHeight, frozenRowCount = _a.frozenRowCount, totalRowCount = _a.totalRowCount, _b = _a.overscan, overscan = _b === void 0 ? 1 : _b, _c = _a.windowSize, windowSize = _c === void 0 ? 1 : _c;
9
+ var scrollTop = _a.scrollTop, viewportHeight = _a.viewportHeight, rowHeight = _a.rowHeight, frozenRowCount = _a.frozenRowCount, totalRowCount = _a.totalRowCount, _b = _a.overscan, overscan = _b === void 0 ? 1 : _b, _c = _a.leadingOverscan, leadingOverscan = _c === void 0 ? 0 : _c, _d = _a.windowSize, windowSize = _d === void 0 ? 1 : _d;
10
10
  var safeRowHeight = Math.max(rowHeight, 1);
11
11
  var safeTotal = Math.max(Math.floor(totalRowCount), 0);
12
12
  var safeFrozen = Math.min(Math.max(Math.floor(frozenRowCount), 0), safeTotal);
@@ -14,11 +14,12 @@ function getVisibleScrollableRowRange(_a) {
14
14
  var relativeStart = Math.min(Math.max(Math.floor(Math.max(scrollTop, 0) / safeRowHeight), 0), scrollableRowCount);
15
15
  var safeWindowSize = Math.max(Math.floor(windowSize), 1);
16
16
  var windowStart = Math.floor(relativeStart / safeWindowSize) * safeWindowSize;
17
- var visibleCount = Math.max(Math.ceil(Math.max(viewportHeight, 0) / safeRowHeight) + Math.max(overscan, 0), 0);
17
+ var renderStart = Math.max(windowStart - Math.max(Math.floor(leadingOverscan), 0), 0);
18
+ var visibleCount = Math.max(Math.ceil(Math.max(viewportHeight, 0) / safeRowHeight) + Math.max(Math.floor(overscan), 0), 0);
18
19
  return {
19
- startRowIndex: safeFrozen + windowStart,
20
+ startRowIndex: safeFrozen + renderStart,
20
21
  endRowIndex: Math.min(safeFrozen + windowStart + visibleCount + safeWindowSize - 1, safeTotal),
21
- paddingTop: windowStart * safeRowHeight,
22
+ paddingTop: renderStart * safeRowHeight,
22
23
  scrollContentHeight: scrollableRowCount * safeRowHeight,
23
24
  };
24
25
  }
@@ -182,6 +182,7 @@ function Table(props) {
182
182
  })));
183
183
  const trHeight = itemHeight + itemPadding * 2;
184
184
  const scrollableBodyHeight = Math.max(contentBodyHeight - frozenRowsHeight, 0);
185
+ const scrollOverscanRows = Math.max(KEYBOARD_NAVIGATION_ROW_WINDOW_SIZE, Math.ceil(scrollableBodyHeight / Math.max(trHeight, 1)));
185
186
  const mainViewportWidth = Math.max(width - (frozenColumnsWidth ?? 0), 0);
186
187
  const logicalBodyContentHeight = data.length * trHeight;
187
188
  const virtualScrollWindowMetrics = React.useMemo(() => getVirtualScrollWindowMetrics({
@@ -199,7 +200,8 @@ function Table(props) {
199
200
  const logicalVerticalScrollState = React.useMemo(() => ({
200
201
  scrollTop,
201
202
  scrollHeight: virtualScrollWindowMetrics.logicalContentHeight,
202
- }), [scrollTop, virtualScrollWindowMetrics.logicalContentHeight]);
203
+ maxScrollTop: virtualScrollWindowMetrics.logicalMaxScroll,
204
+ }), [scrollTop, virtualScrollWindowMetrics.logicalContentHeight, virtualScrollWindowMetrics.logicalMaxScroll]);
203
205
  const hasMultiCellSelection = React.useMemo(() => cellSelectionRanges.length > 1 ||
204
206
  cellSelectionRanges.some(range => {
205
207
  const normalized = normalizeCellSelectionRange(range);
@@ -298,8 +300,10 @@ function Table(props) {
298
300
  rowHeight: trHeight,
299
301
  frozenRowCount,
300
302
  totalRowCount: data.length,
303
+ overscan: scrollOverscanRows,
304
+ leadingOverscan: scrollOverscanRows,
301
305
  windowSize: props.reorder?.enabled ? 1 : KEYBOARD_NAVIGATION_ROW_WINDOW_SIZE,
302
- }), [data.length, frozenRowCount, props.reorder?.enabled, scrollTop, scrollableBodyHeight, trHeight]);
306
+ }), [data.length, frozenRowCount, props.reorder?.enabled, scrollOverscanRows, scrollTop, scrollableBodyHeight, trHeight]);
303
307
  const frozenRowRange = React.useMemo(() => ({ startRowIndex: 0, endRowIndex: frozenRowCount }), [frozenRowCount]);
304
308
  const scrollableRowRange = React.useMemo(() => ({
305
309
  startRowIndex: visibleScrollableRows.startRowIndex,
@@ -2049,7 +2053,13 @@ function Table(props) {
2049
2053
  };
2050
2054
  }, []);
2051
2055
  return (React.createElement(EditorPortalContext.Provider, { value: editorPortalContext },
2052
- React.createElement(Container, { ref: containerRef, role: 'grid', style: { ...style, width, height, borderWidth: `${containerBorderWidth}px` }, className: className, tabIndex: 0, onFocus: event => {
2056
+ React.createElement(Container, { ref: containerRef, role: 'grid', style: {
2057
+ ...style,
2058
+ width,
2059
+ height,
2060
+ borderWidth: `${containerBorderWidth}px`,
2061
+ ['--bgrid-virtual-row-height']: `${trHeight}px`,
2062
+ }, className: className, tabIndex: 0, onFocus: event => {
2053
2063
  if (event.target !== event.currentTarget)
2054
2064
  return;
2055
2065
  const gateway = event.currentTarget.querySelector('[data-bgrid-text-editor-gateway="true"]');
@@ -2085,6 +2095,11 @@ function Table(props) {
2085
2095
  React.createElement(TableSummaryFrozen, { position: 'top' }))),
2086
2096
  React.createElement(Summary, { style: { left: frozenColumnsWidth }, role: 'rfdg-summary' },
2087
2097
  React.createElement(TableSummary, { position: 'top' })))),
2098
+ React.createElement("div", { className: 'bgrid-virtual-row-backdrop', "aria-hidden": 'true', style: {
2099
+ top: stickyTopHeight,
2100
+ height: contentBodyHeight,
2101
+ marginBottom: -contentBodyHeight,
2102
+ } }),
2088
2103
  React.createElement("div", { className: 'bgrid-body-scroll-content', style: { height: virtualScrollWindowMetrics.physicalContentHeight } },
2089
2104
  frozenRowCount > 0 && (React.createElement("div", { className: 'bgrid-frozen-rows-layer', style: { height: frozenRowsHeight, top: stickyTopHeight }, "data-bgrid-row-band": 'frozen' },
2090
2105
  (frozenColumnsWidth ?? 0) > 0 && (React.createElement("div", { className: 'bgrid-frozen-rows-left bgrid-frozen-column-boundary', style: { width: frozenColumnsWidth }, role: 'rfdg-frozen-rows-left' },
@@ -53,7 +53,7 @@ export function ensureCellVisible({ cell, scrollContainer, frozenColumnCount = 0
53
53
  const rowBottom = getRowBottom(targetRowIndex, rowHeight);
54
54
  const clientHeight = scrollContainer.clientHeight;
55
55
  const scrollHeight = verticalScrollState?.scrollHeight ?? scrollContainer.scrollHeight;
56
- const maxScrollTop = Math.max(0, scrollHeight - clientHeight);
56
+ const maxScrollTop = Math.max(0, verticalScrollState?.maxScrollTop ?? scrollHeight - clientHeight);
57
57
  if (clientHeight > 0) {
58
58
  const topInset = clamp(viewportInsets?.top ?? 0, 0, clientHeight);
59
59
  const bottomInset = clamp(viewportInsets?.bottom ?? 0, 0, Math.max(clientHeight - topInset, 0));
@@ -2,7 +2,7 @@
2
2
  * Maps the scrollable body's physical scroll offset to logical data row indexes.
3
3
  * The returned end index is exclusive.
4
4
  */
5
- export function getVisibleScrollableRowRange({ scrollTop, viewportHeight, rowHeight, frozenRowCount, totalRowCount, overscan = 1, windowSize = 1, }) {
5
+ export function getVisibleScrollableRowRange({ scrollTop, viewportHeight, rowHeight, frozenRowCount, totalRowCount, overscan = 1, leadingOverscan = 0, windowSize = 1, }) {
6
6
  const safeRowHeight = Math.max(rowHeight, 1);
7
7
  const safeTotal = Math.max(Math.floor(totalRowCount), 0);
8
8
  const safeFrozen = Math.min(Math.max(Math.floor(frozenRowCount), 0), safeTotal);
@@ -10,11 +10,12 @@ export function getVisibleScrollableRowRange({ scrollTop, viewportHeight, rowHei
10
10
  const relativeStart = Math.min(Math.max(Math.floor(Math.max(scrollTop, 0) / safeRowHeight), 0), scrollableRowCount);
11
11
  const safeWindowSize = Math.max(Math.floor(windowSize), 1);
12
12
  const windowStart = Math.floor(relativeStart / safeWindowSize) * safeWindowSize;
13
- const visibleCount = Math.max(Math.ceil(Math.max(viewportHeight, 0) / safeRowHeight) + Math.max(overscan, 0), 0);
13
+ const renderStart = Math.max(windowStart - Math.max(Math.floor(leadingOverscan), 0), 0);
14
+ const visibleCount = Math.max(Math.ceil(Math.max(viewportHeight, 0) / safeRowHeight) + Math.max(Math.floor(overscan), 0), 0);
14
15
  return {
15
- startRowIndex: safeFrozen + windowStart,
16
+ startRowIndex: safeFrozen + renderStart,
16
17
  endRowIndex: Math.min(safeFrozen + windowStart + visibleCount + safeWindowSize - 1, safeTotal),
17
- paddingTop: windowStart * safeRowHeight,
18
+ paddingTop: renderStart * safeRowHeight,
18
19
  scrollContentHeight: scrollableRowCount * safeRowHeight,
19
20
  };
20
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beautiful-grid",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A beautiful, powerful, open-source React Data Grid.",
5
5
  "homepage": "https://bgrid.axisj.com",
6
6
  "bugs": {
package/style.css CHANGED
@@ -1561,6 +1561,25 @@
1561
1561
  background-color: var(--bgrid-body-bg);
1562
1562
  }
1563
1563
 
1564
+ /* Safari can advance its native scroll layer before React commits the next
1565
+ virtual-row window. Keep an inexpensive viewport-sized row grid behind the
1566
+ real tables so that compositor gaps retain the table's visual geometry. */
1567
+ .bgrid-virtual-row-backdrop {
1568
+ position: sticky;
1569
+ z-index: 0;
1570
+ box-sizing: border-box;
1571
+ min-width: 100%;
1572
+ pointer-events: none;
1573
+ background-color: var(--bgrid-body-bg);
1574
+ background-image: repeating-linear-gradient(
1575
+ to bottom,
1576
+ transparent 0,
1577
+ transparent calc(var(--bgrid-virtual-row-height, 28px) - 1px),
1578
+ var(--bgrid-border-color-base) calc(var(--bgrid-virtual-row-height, 28px) - 1px),
1579
+ var(--bgrid-border-color-base) var(--bgrid-virtual-row-height, 28px)
1580
+ );
1581
+ }
1582
+
1564
1583
  .bgrid-footer-container {
1565
1584
  position: relative;
1566
1585
  z-index: 10;
@@ -15,6 +15,7 @@ export interface EnsureCellVisibleParams {
15
15
  verticalScrollState?: {
16
16
  scrollTop: number;
17
17
  scrollHeight: number;
18
+ maxScrollTop?: number;
18
19
  };
19
20
  viewportInsets?: {
20
21
  top?: number;
@@ -5,6 +5,7 @@ export interface VisibleScrollableRowRangeParams {
5
5
  frozenRowCount: number;
6
6
  totalRowCount: number;
7
7
  overscan?: number;
8
+ leadingOverscan?: number;
8
9
  windowSize?: number;
9
10
  }
10
11
  export interface VisibleScrollableRowRange {
@@ -17,4 +18,4 @@ export interface VisibleScrollableRowRange {
17
18
  * Maps the scrollable body's physical scroll offset to logical data row indexes.
18
19
  * The returned end index is exclusive.
19
20
  */
20
- export declare function getVisibleScrollableRowRange({ scrollTop, viewportHeight, rowHeight, frozenRowCount, totalRowCount, overscan, windowSize, }: VisibleScrollableRowRangeParams): VisibleScrollableRowRange;
21
+ export declare function getVisibleScrollableRowRange({ scrollTop, viewportHeight, rowHeight, frozenRowCount, totalRowCount, overscan, leadingOverscan, windowSize, }: VisibleScrollableRowRangeParams): VisibleScrollableRowRange;