Skip to content

Commit

Permalink
refactor: breaking
Browse files Browse the repository at this point in the history
  • Loading branch information
orefalo committed Oct 15, 2024
1 parent 719b6bc commit e37da53
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 99 deletions.
29 changes: 15 additions & 14 deletions src/lib/SizeAndPositionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,12 @@ export default class SizeAndPositionManager {
const totalSize = this.getTotalSize();
return Math.max(0, Math.min(totalSize - containerSize, idealOffset));
}


// returns an index range
getVisibleRange(
containerSize: number = 0,
offset: number,
windowOverPadding: number
windowOverPaddingCount: number
): VirtualRange {
const totalSize = this.getTotalSize();

Expand All @@ -233,30 +234,30 @@ export default class SizeAndPositionManager {
}

const maxOffset = offset + containerSize;
let start = this.findNearestItem(offset);
let startIdx = this.findNearestItem(offset);

if (start === undefined) {
if (startIdx === undefined) {
throw Error(`Invalid offset ${offset} specified`);
}

const datum = this.getSizeAndPositionForIndex(start);
const datum = this.getSizeAndPositionForIndex(startIdx);
offset = datum.offset + datum.size;

let end = start;
let endIdx = startIdx;

while (offset < maxOffset && end < this.modelCount - 1) {
end++;
offset += this.getSizeAndPositionForIndex(end).size;
while (offset < maxOffset && endIdx < this.modelCount - 1) {
endIdx++;
offset += this.getSizeAndPositionForIndex(endIdx).size;
}

if (windowOverPadding) {
start = Math.max(0, start - windowOverPadding);
end = Math.min(end + windowOverPadding, this.modelCount - 1);
if (windowOverPaddingCount) {
startIdx = Math.max(0, startIdx - windowOverPaddingCount);
endIdx = Math.min(endIdx + windowOverPaddingCount, this.modelCount - 1);
}

return {
start,
end
start: startIdx,
end: endIdx
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/VirtualList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
// positioning
scrollToIndex,
scrollOffset,
windowOverPadding = 3,
windowOverPadding: windowOverPaddingCount = 3,
scrollDirection = DIRECTION.VERTICAL,
scrollToAlignment = ALIGNMENT.AUTO,
scrollToBehaviour = SCROLL_BEHAVIOR.INSTANT,
Expand Down Expand Up @@ -270,7 +270,7 @@
//@ts-expect-error wrong type assignment
scrollDirection === DIRECTION.VERTICAL ? height : width,
offset,
windowOverPadding
windowOverPaddingCount
);
let updatedItems = [];
Expand Down
6 changes: 6 additions & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ export type VirtualItemSize = number | number[] | ((item: unknown, index: number

export { default as VirtualList } from './VirtualList.svelte';

export type SizingCalculatorFn=(index: number, item: unknown) => number

// use by the row() snippet
export interface VirtualListModel {
// the actual item value
item: any;

// The row's index being rendered, from the original dataset
// The index is a string if the IDs are processed via the getKey() function
index: number | string;

// only there if there a custom sizing calculator, calculated size in px
size?: number;
}

export interface VirtualRange {
Expand Down
46 changes: 23 additions & 23 deletions src/lib/new/NewPositionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
* which was forked from react-virtualized.
*/

import { ALIGNMENT, type VirtualRange } from '..';
import { ALIGNMENT, type SizingCalculatorFn, type VirtualRange } from '..';

export default class SizeAndPositionManager {
private model: Array<any>;

// calculate the size of a given index
private sizingCalculator?: (index: number, item: unknown) => number;
private sizingCalculator?: SizingCalculatorFn;
private estimatedSize?: number;

private indexToSizeAndPosition: Record<
Expand All @@ -26,13 +26,11 @@ export default class SizeAndPositionManager {
}
>;
private lastMeasuredIndex: number;

// total viewport size
private totalSize?: number;

constructor(
model: Array<any>,
sizingCalculator?: (index: number, item: unknown) => number,
estimatedSize?: number
) {
constructor(model: Array<any>, sizingCalculator?: SizingCalculatorFn, estimatedSize?: number) {
this.model = model;
this.sizingCalculator = sizingCalculator;
this.estimatedSize = estimatedSize;
Expand All @@ -45,13 +43,13 @@ export default class SizeAndPositionManager {
}

//TODO add model update
updateConfig(itemSize: (index: number, item: unknown) => number, estimatedItemSize?: number) {
mutateState(sizingCalculator: SizingCalculatorFn, estimatedItemSize: number) {
if (estimatedItemSize !== undefined) {
this.estimatedSize = estimatedItemSize;
}

if (itemSize !== undefined) {
this.sizingCalculator = itemSize;
if (sizingCalculator !== undefined) {
this.sizingCalculator = sizingCalculator;
}

this.checkForMismatchItemSizeAndItemCount();
Expand Down Expand Up @@ -221,10 +219,11 @@ export default class SizeAndPositionManager {
return Math.max(0, Math.min(totalSize - containerSize, idealOffset));
}

// returns an index range
getVisibleRange(
containerSize: number = 0,
offset: number,
windowOverPadding: number
windowOverPaddingCount: number
): VirtualRange {
const totalSize = this.getTotalSize();

Expand All @@ -233,30 +232,30 @@ export default class SizeAndPositionManager {
}

const maxOffset = offset + containerSize;
let start = this.findNearestItem(offset);
let startIdx = this.findNearestItem(offset);

if (start === undefined) {
if (startIdx === undefined) {
throw Error(`Invalid offset ${offset} specified`);
}

const datum = this.getSizeAndPositionForIndex(start);
const datum = this.getSizeAndPositionForIndex(startIdx);
offset = datum.offset + datum.size;

let end = start;
let endIdx = startIdx;

while (offset < maxOffset && end < this.model.length - 1) {
end++;
offset += this.getSizeAndPositionForIndex(end).size;
while (offset < maxOffset && endIdx < this.model.length - 1) {
endIdx++;
offset += this.getSizeAndPositionForIndex(endIdx).size;
}

if (windowOverPadding) {
start = Math.max(0, start - windowOverPadding);
end = Math.min(end + windowOverPadding, this.model.length - 1);
if (windowOverPaddingCount) {
startIdx = Math.max(0, startIdx - windowOverPaddingCount);
endIdx = Math.min(endIdx + windowOverPaddingCount, this.model.length - 1);
}

return {
start,
end
start: startIdx,
end: endIdx
};
}

Expand Down Expand Up @@ -329,6 +328,7 @@ export default class SizeAndPositionManager {

while (index < this.model.length && this.getSizeAndPositionForIndex(index).offset < offset) {
index += interval;
//todo interval>>=1
interval *= 2;
}

Expand Down
Loading

0 comments on commit e37da53

Please sign in to comment.