Skip to content

Commit 4814b67

Browse files
committed
fix: new documentatio and code fixes
1 parent e8a924b commit 4814b67

File tree

15 files changed

+157
-1488
lines changed

15 files changed

+157
-1488
lines changed

README.md

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ This package originated from [svelte-tiny-virtual-list](https://github.com/jonas
2525

2626
## Features
2727

28-
-**Svelte 5+ only**
28+
-❺➎⓹**Svelte 5+ only**
2929
Build for Svelte 5+ in Typescript.
3030

3131
- 🚀 **Performant**
@@ -35,7 +35,7 @@ This package originated from [svelte-tiny-virtual-list](https://github.com/jonas
3535
Customize width, heigh, position, style, content.
3636

3737
- 💠 **Layout Control**
38-
Headless, support fixed and variables sizing, along with vertical and horizontal lists.
38+
Headless, support fixed and variables sizing, along with vertical and horizontal lists and tables.
3939

4040
- 🧩 **Programming Interface**
4141
Set positions and properties, raises events on state mutation.
@@ -75,54 +75,41 @@ This component can be used two different ways:
7575
const data = ['A', 'B', 'C', 'D', 'E', 'F' /* ... */];
7676
</script>
7777
78-
<VirtualList width="100%" height={600} model={data} modelCount={data.length} itemSize={50}>
79-
{#snippet slot({ item, style, index })}
80-
<div class="row" {style}>
81-
Item: {item}, Row: #{index}
78+
<VirtualList class='mystyle' style='width:100%;height=600px' items={data}>
79+
{#snippet vl_slot({ index, item })}
80+
<div>
81+
Row: #{index} Item: {item}
8282
</div>
8383
{/snippet}
8484
</VirtualList>
8585
```
8686

87-
You can also perform dynamic loading with a PartialLoader.
88-
89-
```svelte
90-
TODO: explain that model vs views, which translates into model and items
91-
```
92-
9387
### Props
9488

9589
The component accepts the following properties
9690

9791
| Property | Type | Required? | Description |
9892
| ----------------- | ----------- | :-------: | ------------ |
99-
| width | `number` or `string`\* || Width of List. This property will determine the number of rendered items when scrollDirection is `'horizontal'`. |
100-
| height | `number` or `string`\* || Height of List. This property will determine the number of rendered items when scrollDirection is `'vertical'`. |
101-
| model | any[] || the model, the data for the items to display in the list. |
102-
| modelCount | `number` || The number of items you want to render. |
103-
| sizeCalculator | `(index: number, item:any) => number or SizingCalculatorFn` || A function that returns the size (height or width) of the row/column being rendered. the output of this function is used for scrollbar positioning and is passed to the `vl_slot` |
104-
| row | (r:RowAttributes) => SnippetResult || Snippet called to render every item, see description below. |
105-
| scrollDirection | `string` | | Whether the list should scroll vertically or horizontally. One of `'vertical'` (default) or `'horizontal'`. |
106-
| scrollToOffset | `number` | | Can be used to control the scroll offset; Also useful for setting an initial scroll offset. |
107-
| scrollToIndex | `number` | | Item index to scroll to (by forcefully scrolling if necessary). |
108-
| scrollToAlignment | `string` | | Used in combination with `scrollToIndex`, this prop controls the alignment of the scrolled to item. One of: `'start'`, `'center'`, `'end'` or `'auto'`. Use `'start'` to always align items to the top of the container and `'end'` to align them bottom. Use `'center`' to align them in the middle of the container. `'auto'` scrolls the least amount possible to ensure that the specified `scrollToIndex` item is fully visible. |
109-
| scrollToBehaviour | `string` | | Used in combination with `scrollToIndex`, this prop controls the behaviour of the scrolling. One of: `'auto'`, `'smooth'` or `'instant'` (default). |
110-
| windowOverPadding | `number` | | Number of extra items to render above/below the visible items. Tweaking this can help reduce scroll flickering on certain browsers and devices. |
111-
| estimatedItemSize | `number` | | Used to estimate the total size of the list before all of its items have actually been measured. The estimated total height is progressively adjusted as items are rendered. |
93+
| items | any[] || the model, the data for the items to display in the list. |
94+
| vl_slot | (index, item, size) => SnippetResult || Snippet called to render every item, see description below. |
95+
| isHorizontal | boolean (false) | | Whether the list should scroll vertically or horizontally. One of `'vertical'` (default) or `'horizontal'`. |
96+
| isTable | boolean (false) | | Whether the rendering should be a table layout |
97+
| header | () => SnippetResult | | Useful in table mode to render the table header columns. |
98+
| footer | () => SnippetResult | | Useful in table mode to render any table footer. |
99+
| sizeCalculator | `(index: number, item:any) => number alias SizingCalculatorFn` | | Not recommended, as the component will adjust to the css rendering. If you need to control the sizing programmatically, use a function that returns the size (height or width) of the rendered row or column. This function's output is used for scrollbar positioning and is passed to the vl_slot. |
100+
| scrollToOffset | `number` | | It can be used to control the scrollbar offset. **scrollToIndex** and **scrollToOffset** MUST not be used together. |
101+
| scrollToIndex | `number` | | Moved scrollbar to display the given index. Follow scroll behavior and alignment policies. **scrollToIndex** and **scrollToOffset** MUST not be used together. |
102+
| scrollToAlignment | `string` | | Used in combination with **scrollToIndex** and **scrollToOffset**. Use `'start'` to always align items to the top of the container and `'end'` to align them bottom. Use `'center`' to align them in the middle of the container. `'auto'` scrolls the least amount possible to ensure that the specified `scrollToIndex` item is fully visible. |
103+
| scrollToBehaviour | `string` | | Used in combination with **scrollToIndex** and **scrollToOffset**, controls the scrolling behaviour movement. One of: `'auto'`, `'smooth'` or `'instant'` (default). |
112104
| getKey | `(index: number) => any` | | Function that returns the key of an item in the list, which is used to uniquely identify an item. This is useful for dynamic data coming from a database or similar. By default, it's using the item's index. |
113105

114-
_\* `height` must be a number when `scrollDirection` is `'vertical'`. Similarly, `width` must be a number if `scrollDirection` is `'horizontal'`_
115-
_\** `model` is stored, `items` are rendered
116-
117106
### Snippets
118107

119108
- `header` - an optional snippet for the elements that should appear at the top of the list, typically used in table mode
120109
- `footer` - an optional snippet for the elements that should appear at the bottom of the list, typically used in table mode
121110
- `vl_slot` - a required snipper property called to render each row of the list with the signature `vl_slot({index, item, size?})`. `size` is only present if a custom **sizeCalculator** is in place.
122111

123-
124-
125-
for instance,
112+
For instance,
126113

127114
```svelte
128115
<VirtualList items={myModel} style="height:600px">
@@ -138,27 +125,27 @@ for instance,
138125

139126
- `onAfterScroll` - Fired after handling the scroll event
140127

141-
Accepts a function with the following signature `(event: AfterScrollEvent) => void`
128+
Accepts a function with the following signature `(event):VLScrollEvent => void`
142129

143130
```typescript
144-
export interface AfterScrollEvent {
145-
type: 'range.update';
146-
// either the value of `wrapper.scrollTop` or `wrapper.scrollLeft`
147-
offset: number | string;
148-
// the original event
149-
event: Event;
131+
export interface VLScrollEvent {
132+
// either the value of `wrapper.scrollTop` or `wrapper.scrollLeft`
133+
offset: number | string;
134+
// the original event
135+
event: Event;
150136
}
151137
```
152138

153-
- `onVisibleRangeUpdate` - Fired when the visible items are updated
139+
- `onVisibleRangeUpdate` - Fired when the visible window is sliding to display new items
154140

155-
Accepts a function with the following signature `(range: VirtualRange) => void`
141+
Accepts a function with the following signature `(range):VLRange => void`
156142

157143
```typescript
158-
export interface VirtualRangeEvent {
159-
type: 'scroll.update';
160-
start: number; //Index of the first visible item
161-
end: number; //Index of the last visible item
144+
export interface VLRange {
145+
// index of the first visible item
146+
start: number;
147+
// index of the last visible item
148+
end: number;
162149
}
163150
```
164151

src/lib/VirtualListNew.svelte

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@
6262
modelCount?: number;
6363
sizingCalculator?: SizingCalculatorFn;
6464
avgSizeInPx?: number;
65+
clientHeight?: number;
66+
clientWidth?: number;
6567
}
6668
6769
// ====== PROPERTIES ================
@@ -146,7 +148,7 @@
146148
147149
// dom references
148150
let listContainer: HTMLDivElement;
149-
// svelte-ignore non_reactive_update - not sure where its updated?!
151+
// svelte-ignore non_reactive_update
150152
let listInner: HTMLDivElement;
151153
152154
let clientHeight: number = $state(0);
@@ -258,18 +260,13 @@
258260
});
259261
260262
$effect(() => {
261-
// listen to updates:
262263
//@ts-expect-error unused no side effect
263264
scrollToIndex, scrollToAlignment, scrollToOffset, items.length, sizingCalculator;
264265
265-
console.log('propUpdated');
266-
// on update:
267266
propsUpdated();
268267
});
269268
270269
$effect(() => {
271-
console.log('onVisibleRangeUpdate');
272-
273270
if (onVisibleRangeUpdate) {
274271
const vr = getVisibleRange(isHorizontal ? clientWidth : clientHeight, curState.offset);
275272
//onVisibleRangeUpdate({ start: startIdx, end: endIdx });
@@ -292,20 +289,22 @@
292289
prevState = curState;
293290
});
294291
295-
$effect(() => {
296-
//TODO there is a bug with client sizing
297-
console.log('component is resized ' + clientHeight + ' ' + clientWidth);
298-
if (mounted) recomputeSizes(0); // call scroll.reset
299-
});
292+
// $effect(() => {
293+
// //TODO there is a bug with client sizing
294+
// console.log('component is resized ' + clientHeight + ' ' + clientWidth);
295+
// if (mounted) recomputeSizes(0); // call scroll.reset
296+
// });
300297
301298
let prevProps: VProps = {
302-
scrollToIndex,
303-
scrollToAlignment,
304-
scrollToOffset,
305-
modelCount: items.length,
306-
//todo: store a present boolean rather than a ref to the function
307-
sizingCalculator,
308-
avgSizeInPx
299+
// scrollToIndex,
300+
// scrollToAlignment,
301+
// scrollToOffset,
302+
// modelCount: items.length,
303+
// //todo: store a present boolean rather than a ref to the function
304+
// sizingCalculator,
305+
// avgSizeInPx,
306+
// clientHeight,
307+
// clientWidth
309308
};
310309
311310
function propsUpdated() {
@@ -316,19 +315,21 @@
316315
}
317316
318317
const scrollPropsHaveChanged =
319-
prevProps.scrollToIndex !== scrollToIndex ||
320-
prevProps.scrollToAlignment !== scrollToAlignment;
318+
prevProps?.scrollToIndex !== scrollToIndex ||
319+
prevProps?.scrollToAlignment !== scrollToAlignment;
321320
const itemPropsHaveChanged =
322-
prevProps.modelCount !== items.length ||
323-
prevProps.sizingCalculator !== sizingCalculator ||
324-
prevProps.avgSizeInPx !== avgSizeInPx;
321+
prevProps?.modelCount !== items.length ||
322+
prevProps?.sizingCalculator !== sizingCalculator ||
323+
prevProps?.avgSizeInPx !== avgSizeInPx ||
324+
prevProps?.clientHeight !== clientHeight ||
325+
prevProps?.clientWidth !== clientWidth;
325326
326327
if (itemPropsHaveChanged) {
327328
// sizeAndPositionManager.updateConfig(itemSize, modelCount, estimatedItemSize);
328329
recomputeSizes();
329330
}
330331
331-
const scrollOffsetHaveChanged = prevProps.scrollToOffset !== scrollToOffset;
332+
const scrollOffsetHaveChanged = prevProps?.scrollToOffset !== scrollToOffset;
332333
if (scrollOffsetHaveChanged) {
333334
curState = {
334335
offset: scrollToOffset || 0,
@@ -350,7 +351,9 @@
350351
scrollToOffset,
351352
modelCount: items.length,
352353
sizingCalculator,
353-
avgSizeInPx
354+
avgSizeInPx,
355+
clientHeight,
356+
clientWidth
354357
};
355358
}
356359

src/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface VLSlotSignature {
1616
size?: number;
1717
}
1818

19+
//TODO VLRangeEvent?
1920
export interface VLRange {
2021
// index of the first visible item
2122
start: number;

0 commit comments

Comments
 (0)