@revolist/revogrid 3.6.1 → 3.6.3

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.
@@ -28,10 +28,7 @@ items, realCount, virtualSize, dimension) {
28
28
  toUpdate = recombineByOffset(Math.abs(changedOffsetStart), Object.assign(Object.assign({ positiveDirection: changedOffsetStart > -1 }, dimension), items));
29
29
  }
30
30
  }
31
- // virtual size can differ based on scroll position if some big items are present
32
- // scroll can be in the middle of item and virtual size will be larger
33
- // so we need to exclude this part from virtual size hence it's already passed
34
- const maxSizeVirtualSize = Math.min(virtualSize + (activeItem.end - activeItem.start), dimension.realSize);
31
+ const maxSizeVirtualSize = getMaxVirtualSize(virtualSize, dimension.realSize, activeItem);
35
32
  // if partial recombination add items if revo-viewport has some space left
36
33
  if (toUpdate) {
37
34
  const extra = addMissingItems(activeItem, realCount, maxSizeVirtualSize, toUpdate, dimension);
@@ -58,6 +55,12 @@ items, realCount, virtualSize, dimension) {
58
55
  }
59
56
  return toUpdate;
60
57
  }
58
+ // virtual size can differ based on scroll position if some big items are present
59
+ // scroll can be in the middle of item and virtual size will be larger
60
+ // so we need to exclude this part from virtual size hence it's already passed
61
+ function getMaxVirtualSize(virtualSize, realSize, activeItem) {
62
+ return Math.min(virtualSize + (activeItem.end - activeItem.start), realSize);
63
+ }
61
64
  function updateMissingAndRange(items, missing, range) {
62
65
  items.splice(range.end + 1, 0, ...missing);
63
66
  // update range if start larger after recombination
@@ -189,8 +192,24 @@ function getItemSize(index, sizes, origSize = 0) {
189
192
  }
190
193
  return origSize;
191
194
  }
192
- function isActiveRange(pos, item) {
193
- return item && pos >= item.start && pos <= item.end;
195
+ /**
196
+ * Verify if position is in range of the PositionItem, start and end are included
197
+ */
198
+ function isActiveRange(pos, realSize, first, last) {
199
+ if (!first || !last) {
200
+ return false;
201
+ }
202
+ // if position is in range of first item
203
+ // or position is after first item and last item is the last item in real size
204
+ return pos >= first.start && pos <= first.end ||
205
+ pos > first.end && last.end === realSize;
206
+ }
207
+ function isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem) {
208
+ // if no first item, means no items in viewport
209
+ if (!firstItem) {
210
+ return false;
211
+ }
212
+ return virtualSize + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end);
194
213
  }
195
214
  function getFirstItem(s) {
196
215
  return s.items[s.start];
@@ -267,31 +286,37 @@ class ViewportStore {
267
286
  return;
268
287
  }
269
288
  const frameOffset = dimension.frameOffset;
270
- const outsize = frameOffset * 2 * dimension.originItemSize;
289
+ const singleOffsetInPx = dimension.originItemSize * frameOffset;
290
+ // add offset to virtual size from both sides
291
+ const outsize = singleOffsetInPx * 2;
271
292
  virtualSize += outsize;
272
- let maxCoordinate = virtualSize;
273
- // if real size is bigger than virtual size, then the end will be real size decreased by virtual size
274
- // but sometimes the real size slightly bigger than virtual size, so we need to check it and fallback max coordinate to virtual size
293
+ // expected no scroll if real size less than virtual size, position is 0
294
+ let maxCoordinate = 0;
295
+ // if there is nodes outside of viewport, max coordinate has to be adjusted
275
296
  if (dimension.realSize > virtualSize) {
276
- maxCoordinate = Math.max(dimension.realSize - virtualSize, virtualSize);
297
+ // max coordinate is real size minus virtual/rendered space
298
+ maxCoordinate = dimension.realSize - virtualSize;
277
299
  }
278
300
  let toUpdate = {
279
301
  lastCoordinate: position,
280
302
  };
281
303
  let pos = position;
282
- pos -= frameOffset * dimension.originItemSize;
283
- pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate; // todo: check if maxCoordinate can be removed
284
- const firstItem = getFirstItem(this.getItems());
285
- const lastItem = getLastItem(this.getItems());
304
+ pos -= singleOffsetInPx;
305
+ pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate;
306
+ const allItems = this.getItems();
307
+ const firstItem = getFirstItem(allItems);
308
+ const lastItem = getLastItem(allItems);
286
309
  // left position changed
287
- if (!isActiveRange(pos, firstItem)) {
288
- toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, this.getItems(), this.store.get('realCount'), virtualSize, dimension));
310
+ // verify if new position is in range of previously rendered first item
311
+ if (!isActiveRange(pos, dimension.realSize, firstItem, lastItem)) {
312
+ toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, allItems, this.store.get('realCount'), virtualSize, dimension));
289
313
  this.setViewport(Object.assign({}, toUpdate));
290
314
  // right position changed
291
315
  }
292
- else if (firstItem && this.store.get('virtualSize') + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end)) {
316
+ else if (isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem)) {
293
317
  // check is any item missing for full fill content
294
- const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, this.getItems(), dimension);
318
+ const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, allItems, dimension);
319
+ // update missing items
295
320
  if (missing.length) {
296
321
  const items = [...this.store.get('items')];
297
322
  const range = {
@@ -319,7 +344,6 @@ class ViewportStore {
319
344
  if (dropToOriginalSize) {
320
345
  items = setItemSizes(items, start, dropToOriginalSize, this.store.get('lastCoordinate'));
321
346
  }
322
- console.log('items', items);
323
347
  // loop through array from initial item after recombination
324
348
  while (i < count) {
325
349
  const item = items[start];
@@ -4525,10 +4525,7 @@ items, realCount, virtualSize, dimension) {
4525
4525
  toUpdate = recombineByOffset(Math.abs(changedOffsetStart), Object.assign(Object.assign({ positiveDirection: changedOffsetStart > -1 }, dimension), items));
4526
4526
  }
4527
4527
  }
4528
- // virtual size can differ based on scroll position if some big items are present
4529
- // scroll can be in the middle of item and virtual size will be larger
4530
- // so we need to exclude this part from virtual size hence it's already passed
4531
- const maxSizeVirtualSize = Math.min(virtualSize + (activeItem.end - activeItem.start), dimension.realSize);
4528
+ const maxSizeVirtualSize = getMaxVirtualSize(virtualSize, dimension.realSize, activeItem);
4532
4529
  // if partial recombination add items if revo-viewport has some space left
4533
4530
  if (toUpdate) {
4534
4531
  const extra = addMissingItems(activeItem, realCount, maxSizeVirtualSize, toUpdate, dimension);
@@ -4555,6 +4552,12 @@ items, realCount, virtualSize, dimension) {
4555
4552
  }
4556
4553
  return toUpdate;
4557
4554
  }
4555
+ // virtual size can differ based on scroll position if some big items are present
4556
+ // scroll can be in the middle of item and virtual size will be larger
4557
+ // so we need to exclude this part from virtual size hence it's already passed
4558
+ function getMaxVirtualSize(virtualSize, realSize, activeItem) {
4559
+ return Math.min(virtualSize + (activeItem.end - activeItem.start), realSize);
4560
+ }
4558
4561
  function updateMissingAndRange(items, missing, range) {
4559
4562
  items.splice(range.end + 1, 0, ...missing);
4560
4563
  // update range if start larger after recombination
@@ -4686,8 +4689,24 @@ function getItemSize(index, sizes, origSize = 0) {
4686
4689
  }
4687
4690
  return origSize;
4688
4691
  }
4689
- function isActiveRange(pos, item) {
4690
- return item && pos >= item.start && pos <= item.end;
4692
+ /**
4693
+ * Verify if position is in range of the PositionItem, start and end are included
4694
+ */
4695
+ function isActiveRange(pos, realSize, first, last) {
4696
+ if (!first || !last) {
4697
+ return false;
4698
+ }
4699
+ // if position is in range of first item
4700
+ // or position is after first item and last item is the last item in real size
4701
+ return pos >= first.start && pos <= first.end ||
4702
+ pos > first.end && last.end === realSize;
4703
+ }
4704
+ function isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem) {
4705
+ // if no first item, means no items in viewport
4706
+ if (!firstItem) {
4707
+ return false;
4708
+ }
4709
+ return virtualSize + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end);
4691
4710
  }
4692
4711
  function getFirstItem(s) {
4693
4712
  return s.items[s.start];
@@ -4764,31 +4783,37 @@ class ViewportStore {
4764
4783
  return;
4765
4784
  }
4766
4785
  const frameOffset = dimension.frameOffset;
4767
- const outsize = frameOffset * 2 * dimension.originItemSize;
4786
+ const singleOffsetInPx = dimension.originItemSize * frameOffset;
4787
+ // add offset to virtual size from both sides
4788
+ const outsize = singleOffsetInPx * 2;
4768
4789
  virtualSize += outsize;
4769
- let maxCoordinate = virtualSize;
4770
- // if real size is bigger than virtual size, then the end will be real size decreased by virtual size
4771
- // but sometimes the real size slightly bigger than virtual size, so we need to check it and fallback max coordinate to virtual size
4790
+ // expected no scroll if real size less than virtual size, position is 0
4791
+ let maxCoordinate = 0;
4792
+ // if there is nodes outside of viewport, max coordinate has to be adjusted
4772
4793
  if (dimension.realSize > virtualSize) {
4773
- maxCoordinate = Math.max(dimension.realSize - virtualSize, virtualSize);
4794
+ // max coordinate is real size minus virtual/rendered space
4795
+ maxCoordinate = dimension.realSize - virtualSize;
4774
4796
  }
4775
4797
  let toUpdate = {
4776
4798
  lastCoordinate: position,
4777
4799
  };
4778
4800
  let pos = position;
4779
- pos -= frameOffset * dimension.originItemSize;
4780
- pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate; // todo: check if maxCoordinate can be removed
4781
- const firstItem = getFirstItem(this.getItems());
4782
- const lastItem = getLastItem(this.getItems());
4801
+ pos -= singleOffsetInPx;
4802
+ pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate;
4803
+ const allItems = this.getItems();
4804
+ const firstItem = getFirstItem(allItems);
4805
+ const lastItem = getLastItem(allItems);
4783
4806
  // left position changed
4784
- if (!isActiveRange(pos, firstItem)) {
4785
- toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, this.getItems(), this.store.get('realCount'), virtualSize, dimension));
4807
+ // verify if new position is in range of previously rendered first item
4808
+ if (!isActiveRange(pos, dimension.realSize, firstItem, lastItem)) {
4809
+ toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, allItems, this.store.get('realCount'), virtualSize, dimension));
4786
4810
  this.setViewport(Object.assign({}, toUpdate));
4787
4811
  // right position changed
4788
4812
  }
4789
- else if (firstItem && this.store.get('virtualSize') + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end)) {
4813
+ else if (isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem)) {
4790
4814
  // check is any item missing for full fill content
4791
- const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, this.getItems(), dimension);
4815
+ const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, allItems, dimension);
4816
+ // update missing items
4792
4817
  if (missing.length) {
4793
4818
  const items = [...this.store.get('items')];
4794
4819
  const range = {
@@ -4816,7 +4841,6 @@ class ViewportStore {
4816
4841
  if (dropToOriginalSize) {
4817
4842
  items = setItemSizes(items, start, dropToOriginalSize, this.store.get('lastCoordinate'));
4818
4843
  }
4819
- console.log('items', items);
4820
4844
  // loop through array from initial item after recombination
4821
4845
  while (i < count) {
4822
4846
  const item = items[start];
@@ -21,10 +21,7 @@ items, realCount, virtualSize, dimension) {
21
21
  toUpdate = recombineByOffset(Math.abs(changedOffsetStart), Object.assign(Object.assign({ positiveDirection: changedOffsetStart > -1 }, dimension), items));
22
22
  }
23
23
  }
24
- // virtual size can differ based on scroll position if some big items are present
25
- // scroll can be in the middle of item and virtual size will be larger
26
- // so we need to exclude this part from virtual size hence it's already passed
27
- const maxSizeVirtualSize = Math.min(virtualSize + (activeItem.end - activeItem.start), dimension.realSize);
24
+ const maxSizeVirtualSize = getMaxVirtualSize(virtualSize, dimension.realSize, activeItem);
28
25
  // if partial recombination add items if revo-viewport has some space left
29
26
  if (toUpdate) {
30
27
  const extra = addMissingItems(activeItem, realCount, maxSizeVirtualSize, toUpdate, dimension);
@@ -51,6 +48,12 @@ items, realCount, virtualSize, dimension) {
51
48
  }
52
49
  return toUpdate;
53
50
  }
51
+ // virtual size can differ based on scroll position if some big items are present
52
+ // scroll can be in the middle of item and virtual size will be larger
53
+ // so we need to exclude this part from virtual size hence it's already passed
54
+ function getMaxVirtualSize(virtualSize, realSize, activeItem) {
55
+ return Math.min(virtualSize + (activeItem.end - activeItem.start), realSize);
56
+ }
54
57
  export function updateMissingAndRange(items, missing, range) {
55
58
  items.splice(range.end + 1, 0, ...missing);
56
59
  // update range if start larger after recombination
@@ -182,8 +185,24 @@ function getItemSize(index, sizes, origSize = 0) {
182
185
  }
183
186
  return origSize;
184
187
  }
185
- export function isActiveRange(pos, item) {
186
- return item && pos >= item.start && pos <= item.end;
188
+ /**
189
+ * Verify if position is in range of the PositionItem, start and end are included
190
+ */
191
+ export function isActiveRange(pos, realSize, first, last) {
192
+ if (!first || !last) {
193
+ return false;
194
+ }
195
+ // if position is in range of first item
196
+ // or position is after first item and last item is the last item in real size
197
+ return pos >= first.start && pos <= first.end ||
198
+ pos > first.end && last.end === realSize;
199
+ }
200
+ export function isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem) {
201
+ // if no first item, means no items in viewport
202
+ if (!firstItem) {
203
+ return false;
204
+ }
205
+ return virtualSize + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end);
187
206
  }
188
207
  export function getFirstItem(s) {
189
208
  return s.items[s.start];
@@ -7,7 +7,7 @@
7
7
  * Redraw items during scrolling
8
8
  */
9
9
  import { createStore } from '@stencil/store';
10
- import { addMissingItems, getFirstItem, getLastItem, getUpdatedItemsByPosition, isActiveRange, setItemSizes, updateMissingAndRange } from './viewport.helpers';
10
+ import { addMissingItems, getFirstItem, getLastItem, getUpdatedItemsByPosition, isActiveRange, isActiveRangeOutsideLastItem, setItemSizes, updateMissingAndRange } from './viewport.helpers';
11
11
  import { setStore } from '../../utils/store.utils';
12
12
  function initialState() {
13
13
  return {
@@ -37,31 +37,37 @@ export default class ViewportStore {
37
37
  return;
38
38
  }
39
39
  const frameOffset = dimension.frameOffset;
40
- const outsize = frameOffset * 2 * dimension.originItemSize;
40
+ const singleOffsetInPx = dimension.originItemSize * frameOffset;
41
+ // add offset to virtual size from both sides
42
+ const outsize = singleOffsetInPx * 2;
41
43
  virtualSize += outsize;
42
- let maxCoordinate = virtualSize;
43
- // if real size is bigger than virtual size, then the end will be real size decreased by virtual size
44
- // but sometimes the real size slightly bigger than virtual size, so we need to check it and fallback max coordinate to virtual size
44
+ // expected no scroll if real size less than virtual size, position is 0
45
+ let maxCoordinate = 0;
46
+ // if there is nodes outside of viewport, max coordinate has to be adjusted
45
47
  if (dimension.realSize > virtualSize) {
46
- maxCoordinate = Math.max(dimension.realSize - virtualSize, virtualSize);
48
+ // max coordinate is real size minus virtual/rendered space
49
+ maxCoordinate = dimension.realSize - virtualSize;
47
50
  }
48
51
  let toUpdate = {
49
52
  lastCoordinate: position,
50
53
  };
51
54
  let pos = position;
52
- pos -= frameOffset * dimension.originItemSize;
53
- pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate; // todo: check if maxCoordinate can be removed
54
- const firstItem = getFirstItem(this.getItems());
55
- const lastItem = getLastItem(this.getItems());
55
+ pos -= singleOffsetInPx;
56
+ pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate;
57
+ const allItems = this.getItems();
58
+ const firstItem = getFirstItem(allItems);
59
+ const lastItem = getLastItem(allItems);
56
60
  // left position changed
57
- if (!isActiveRange(pos, firstItem)) {
58
- toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, this.getItems(), this.store.get('realCount'), virtualSize, dimension));
61
+ // verify if new position is in range of previously rendered first item
62
+ if (!isActiveRange(pos, dimension.realSize, firstItem, lastItem)) {
63
+ toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, allItems, this.store.get('realCount'), virtualSize, dimension));
59
64
  this.setViewport(Object.assign({}, toUpdate));
60
65
  // right position changed
61
66
  }
62
- else if (firstItem && this.store.get('virtualSize') + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end)) {
67
+ else if (isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem)) {
63
68
  // check is any item missing for full fill content
64
- const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, this.getItems(), dimension);
69
+ const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, allItems, dimension);
70
+ // update missing items
65
71
  if (missing.length) {
66
72
  const items = [...this.store.get('items')];
67
73
  const range = {
@@ -89,7 +95,6 @@ export default class ViewportStore {
89
95
  if (dropToOriginalSize) {
90
96
  items = setItemSizes(items, start, dropToOriginalSize, this.store.get('lastCoordinate'));
91
97
  }
92
- console.log('items', items);
93
98
  // loop through array from initial item after recombination
94
99
  while (i < count) {
95
100
  const item = items[start];
@@ -67,9 +67,15 @@ export function generateFakeDataObject(config = {}) {
67
67
  prop: rgCol,
68
68
  filter:"myFilterType",
69
69
  sortable: true,
70
- size: 200,
70
+ size: 140,
71
71
  cellCompare: (rgCol % 2) == 0 ? naturalSort : undefined
72
72
  };
73
+
74
+ if (rgCol == 0) {
75
+ columns[rgCol].size = 433;
76
+ } else if (rgCol == 10) {
77
+ columns[rgCol].size = 200;
78
+ }
73
79
 
74
80
  // apply config
75
81
  if (colPinStart.indexOf(j) > -1) {
@@ -4521,10 +4521,7 @@ items, realCount, virtualSize, dimension) {
4521
4521
  toUpdate = recombineByOffset(Math.abs(changedOffsetStart), Object.assign(Object.assign({ positiveDirection: changedOffsetStart > -1 }, dimension), items));
4522
4522
  }
4523
4523
  }
4524
- // virtual size can differ based on scroll position if some big items are present
4525
- // scroll can be in the middle of item and virtual size will be larger
4526
- // so we need to exclude this part from virtual size hence it's already passed
4527
- const maxSizeVirtualSize = Math.min(virtualSize + (activeItem.end - activeItem.start), dimension.realSize);
4524
+ const maxSizeVirtualSize = getMaxVirtualSize(virtualSize, dimension.realSize, activeItem);
4528
4525
  // if partial recombination add items if revo-viewport has some space left
4529
4526
  if (toUpdate) {
4530
4527
  const extra = addMissingItems(activeItem, realCount, maxSizeVirtualSize, toUpdate, dimension);
@@ -4551,6 +4548,12 @@ items, realCount, virtualSize, dimension) {
4551
4548
  }
4552
4549
  return toUpdate;
4553
4550
  }
4551
+ // virtual size can differ based on scroll position if some big items are present
4552
+ // scroll can be in the middle of item and virtual size will be larger
4553
+ // so we need to exclude this part from virtual size hence it's already passed
4554
+ function getMaxVirtualSize(virtualSize, realSize, activeItem) {
4555
+ return Math.min(virtualSize + (activeItem.end - activeItem.start), realSize);
4556
+ }
4554
4557
  function updateMissingAndRange(items, missing, range) {
4555
4558
  items.splice(range.end + 1, 0, ...missing);
4556
4559
  // update range if start larger after recombination
@@ -4682,8 +4685,24 @@ function getItemSize(index, sizes, origSize = 0) {
4682
4685
  }
4683
4686
  return origSize;
4684
4687
  }
4685
- function isActiveRange(pos, item) {
4686
- return item && pos >= item.start && pos <= item.end;
4688
+ /**
4689
+ * Verify if position is in range of the PositionItem, start and end are included
4690
+ */
4691
+ function isActiveRange(pos, realSize, first, last) {
4692
+ if (!first || !last) {
4693
+ return false;
4694
+ }
4695
+ // if position is in range of first item
4696
+ // or position is after first item and last item is the last item in real size
4697
+ return pos >= first.start && pos <= first.end ||
4698
+ pos > first.end && last.end === realSize;
4699
+ }
4700
+ function isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem) {
4701
+ // if no first item, means no items in viewport
4702
+ if (!firstItem) {
4703
+ return false;
4704
+ }
4705
+ return virtualSize + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end);
4687
4706
  }
4688
4707
  function getFirstItem(s) {
4689
4708
  return s.items[s.start];
@@ -4760,31 +4779,37 @@ class ViewportStore {
4760
4779
  return;
4761
4780
  }
4762
4781
  const frameOffset = dimension.frameOffset;
4763
- const outsize = frameOffset * 2 * dimension.originItemSize;
4782
+ const singleOffsetInPx = dimension.originItemSize * frameOffset;
4783
+ // add offset to virtual size from both sides
4784
+ const outsize = singleOffsetInPx * 2;
4764
4785
  virtualSize += outsize;
4765
- let maxCoordinate = virtualSize;
4766
- // if real size is bigger than virtual size, then the end will be real size decreased by virtual size
4767
- // but sometimes the real size slightly bigger than virtual size, so we need to check it and fallback max coordinate to virtual size
4786
+ // expected no scroll if real size less than virtual size, position is 0
4787
+ let maxCoordinate = 0;
4788
+ // if there is nodes outside of viewport, max coordinate has to be adjusted
4768
4789
  if (dimension.realSize > virtualSize) {
4769
- maxCoordinate = Math.max(dimension.realSize - virtualSize, virtualSize);
4790
+ // max coordinate is real size minus virtual/rendered space
4791
+ maxCoordinate = dimension.realSize - virtualSize;
4770
4792
  }
4771
4793
  let toUpdate = {
4772
4794
  lastCoordinate: position,
4773
4795
  };
4774
4796
  let pos = position;
4775
- pos -= frameOffset * dimension.originItemSize;
4776
- pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate; // todo: check if maxCoordinate can be removed
4777
- const firstItem = getFirstItem(this.getItems());
4778
- const lastItem = getLastItem(this.getItems());
4797
+ pos -= singleOffsetInPx;
4798
+ pos = pos < 0 ? 0 : pos < maxCoordinate ? pos : maxCoordinate;
4799
+ const allItems = this.getItems();
4800
+ const firstItem = getFirstItem(allItems);
4801
+ const lastItem = getLastItem(allItems);
4779
4802
  // left position changed
4780
- if (!isActiveRange(pos, firstItem)) {
4781
- toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, this.getItems(), this.store.get('realCount'), virtualSize, dimension));
4803
+ // verify if new position is in range of previously rendered first item
4804
+ if (!isActiveRange(pos, dimension.realSize, firstItem, lastItem)) {
4805
+ toUpdate = Object.assign(Object.assign({}, toUpdate), getUpdatedItemsByPosition(pos, allItems, this.store.get('realCount'), virtualSize, dimension));
4782
4806
  this.setViewport(Object.assign({}, toUpdate));
4783
4807
  // right position changed
4784
4808
  }
4785
- else if (firstItem && this.store.get('virtualSize') + pos > (lastItem === null || lastItem === void 0 ? void 0 : lastItem.end)) {
4809
+ else if (isActiveRangeOutsideLastItem(pos, virtualSize, firstItem, lastItem)) {
4786
4810
  // check is any item missing for full fill content
4787
- const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, this.getItems(), dimension);
4811
+ const missing = addMissingItems(firstItem, this.store.get('realCount'), virtualSize + pos - firstItem.start, allItems, dimension);
4812
+ // update missing items
4788
4813
  if (missing.length) {
4789
4814
  const items = [...this.store.get('items')];
4790
4815
  const range = {
@@ -4812,7 +4837,6 @@ class ViewportStore {
4812
4837
  if (dropToOriginalSize) {
4813
4838
  items = setItemSizes(items, start, dropToOriginalSize, this.store.get('lastCoordinate'));
4814
4839
  }
4815
- console.log('items', items);
4816
4840
  // loop through array from initial item after recombination
4817
4841
  while (i < count) {
4818
4842
  const item = items[start];