@vaadin/vaadin-virtual-list
Advanced tools
{ | ||
"name": "@vaadin/vaadin-virtual-list", | ||
"version": "21.0.0-alpha1", | ||
"description": "vaadin-virtual-list", | ||
"version": "21.0.0-alpha10", | ||
"description": "Web Component for displaying a virtual/infinite list or items.", | ||
"main": "vaadin-virtual-list.js", | ||
"module": "vaadin-virtual-list.js", | ||
"repository": "vaadin/vaadin-virtual-list", | ||
"repository": "vaadin/web-components", | ||
"keywords": [ | ||
@@ -24,4 +24,12 @@ "Vaadin", | ||
"vaadin-*.js", | ||
"src" | ||
"src", | ||
"theme" | ||
], | ||
"dependencies": { | ||
"@polymer/polymer": "^3.0.0", | ||
"@vaadin/vaadin-element-mixin": "^21.0.0-alpha10", | ||
"@vaadin/vaadin-lumo-styles": "^21.0.0-alpha10", | ||
"@vaadin/vaadin-material-styles": "^21.0.0-alpha10", | ||
"@vaadin/vaadin-themable-mixin": "^21.0.0-alpha10" | ||
}, | ||
"devDependencies": { | ||
@@ -35,3 +43,3 @@ "@esm-bundle/chai": "^4.1.5", | ||
}, | ||
"gitHead": "8542c7dadc4c86e454a48613f0f2d027dcb5aa86" | ||
"gitHead": "9e75b3416edc041e35720c29a842423a1da66e60" | ||
} |
@@ -1,1 +0,73 @@ | ||
<!-- To be implemented in https://github.com/vaadin/web-components/issues/283 --> | ||
# <vaadin-virtual-list> | ||
[Live Demo ↗](https://vaadin.com/docs/latest/ds/components/virtual-list) | ||
| | ||
[API documentation ↗](https://vaadin.com/docs/latest/ds/components/virtual-list/api) | ||
[<vaadin-virtual-list>](https://vaadin.com/docs/latest/ds/components/virtual-list) is a Web Component providing an accessible and customizable virtual-list, part of the [Vaadin components](https://vaadin.com/docs/latest/ds/components). | ||
[](https://www.npmjs.com/package/@vaadin/vaadin-virtual-list) | ||
```html | ||
<vaadin-virtual-list></vaadin-virtual-list> | ||
<script> | ||
const list = document.querySelector('vaadin-virtual-list'); | ||
list.items = items; // An array of data items | ||
list.renderer = (root, list, {item, index}) => { | ||
root.textContent = `#${index}: ${item.name}` | ||
} | ||
</script> | ||
``` | ||
[<img src="https://raw.githubusercontent.com/vaadin/web-components/master/packages/virtual-list/screenshot.png" alt="Screenshot of vaadin-virtual-list">](https://vaadin.com/docs/latest/ds/components/virtual-list) | ||
## Installation | ||
Install `vaadin-virtual-list`: | ||
```sh | ||
npm i @vaadin/vaadin-virtual-list --save | ||
``` | ||
Once installed, import it in your application: | ||
```js | ||
import '@vaadin/vaadin-virtual-list/vaadin-virtual-list.js'; | ||
``` | ||
## Getting started | ||
Vaadin components use the Lumo theme by default. | ||
To use the Material theme, import the correspondent file from the `theme/material` folder. | ||
## Entry points | ||
- The component with the Lumo theme: | ||
`theme/lumo/vaadin-virtual-list.js` | ||
- The component with the Material theme: | ||
`theme/material/vaadin-virtual-list.js` | ||
- Alias for `theme/lumo/vaadin-virtual-list.js`: | ||
`vaadin-virtual-list.js` | ||
## Big Thanks | ||
Cross-browser Testing Platform and Open Source <3 Provided by [Sauce Labs](https://saucelabs.com). | ||
## Contributing | ||
To contribute to the component, please read [the guideline](https://github.com/vaadin/vaadin-core/blob/master/CONTRIBUTING.md) first. | ||
## License | ||
Apache License 2.0 | ||
Vaadin collects development time usage statistics to improve this product. For details and to opt-out, see https://github.com/vaadin/vaadin-usage-statistics. |
@@ -21,2 +21,4 @@ import { timeOut, animationFrame } from './async.js'; | ||
this.__safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); | ||
this.timeouts = { | ||
@@ -64,4 +66,12 @@ SCROLL_REORDER: 500, | ||
get adjustedFirstVisibleIndex() { | ||
return this.firstVisibleIndex + this._vidxOffset; | ||
} | ||
get adjustedLastVisibleIndex() { | ||
return this.lastVisibleIndex + this._vidxOffset; | ||
} | ||
scrollToIndex(index) { | ||
if (typeof index !== 'number' || isNaN(index) || !this.scrollTarget.offsetHeight) { | ||
if (typeof index !== 'number' || isNaN(index) || this.size === 0 || !this.scrollTarget.offsetHeight) { | ||
return; | ||
@@ -108,3 +118,3 @@ } | ||
if (el.__virtualIndex >= startIndex && el.__virtualIndex <= endIndex) { | ||
this.updateElement(el, el.__virtualIndex); | ||
this.__updateElement(el, el.__virtualIndex); | ||
} | ||
@@ -114,2 +124,19 @@ }); | ||
__updateElement(el, index) { | ||
// Clean up temporary min height | ||
if (el.style.minHeight) { | ||
el.style.minHeight = ''; | ||
} | ||
this.updateElement(el, index); | ||
if (el.offsetHeight === 0) { | ||
// If the elements have 0 height after update (for example due to lazy rendering), | ||
// it results in iron-list requesting to create an unlimited count of elements. | ||
// Assign a temporary min height to elements that would otherwise end up having | ||
// no height. | ||
el.style.minHeight = '200px'; | ||
} | ||
} | ||
__getIndexScrollOffset(index) { | ||
@@ -125,6 +152,11 @@ const element = this.__getVisibleElements().find((el) => el.__virtualIndex === index); | ||
let fvi = this.firstVisibleIndex + this._vidxOffset; | ||
// Record the scroll position before changing the size | ||
let fvi; // first visible index | ||
let fviOffsetBefore; // scroll offset of the first visible index | ||
if (size > 0) { | ||
fvi = this.firstVisibleIndex + this._vidxOffset; | ||
fviOffsetBefore = this.__getIndexScrollOffset(fvi); | ||
} | ||
const fviOffsetBefore = this.__getIndexScrollOffset(fvi); | ||
// Change the size | ||
this.__size = size; | ||
@@ -134,9 +166,13 @@ this._itemsChanged({ | ||
}); | ||
flush(); | ||
fvi = Math.min(fvi, size - 1); | ||
this.scrollToIndex(fvi); | ||
// Try to restore the scroll position if the new size is larger than 0 | ||
if (size > 0) { | ||
fvi = Math.min(fvi, size - 1); | ||
this.scrollToIndex(fvi); | ||
const fviOffsetAfter = this.__getIndexScrollOffset(fvi); | ||
if (fviOffsetBefore !== undefined && fviOffsetAfter !== undefined) { | ||
this._scrollTop += fviOffsetBefore - fviOffsetAfter; | ||
const fviOffsetAfter = this.__getIndexScrollOffset(fvi); | ||
if (fviOffsetBefore !== undefined && fviOffsetAfter !== undefined) { | ||
this._scrollTop += fviOffsetBefore - fviOffsetAfter; | ||
} | ||
} | ||
@@ -216,3 +252,3 @@ | ||
el.__virtualIndex = vidx + (this._vidxOffset || 0); | ||
this.updateElement(el, el.__virtualIndex); | ||
this.__updateElement(el, el.__virtualIndex); | ||
} | ||
@@ -393,2 +429,11 @@ }, itemSet); | ||
} | ||
// Due to a rendering bug, reordering the rows can make parts of the scroll target disappear | ||
// on Safari when using sticky positioning in case the scroll target is inside a flexbox. | ||
// This issue manifests with grid (the header can disappear if grid is used inside a flexbox) | ||
if (this.__safari) { | ||
const { transform } = this.scrollTarget.style; | ||
this.scrollTarget.style.transform = 'translateZ(0)'; | ||
setTimeout(() => (this.scrollTarget.style.transform = transform)); | ||
} | ||
} | ||
@@ -395,0 +440,0 @@ |
@@ -65,2 +65,20 @@ import { IronListAdapter } from './virtualizer-iron-list-adapter.js'; | ||
} | ||
/** | ||
* Gets the index of the first visible item in the viewport. | ||
* | ||
* @return {number} | ||
*/ | ||
get firstVisibleIndex() { | ||
return this.__adapter.adjustedFirstVisibleIndex; | ||
} | ||
/** | ||
* Gets the index of the last visible item in the viewport. | ||
* | ||
* @return {number} | ||
*/ | ||
get lastVisibleIndex() { | ||
return this.__adapter.adjustedLastVisibleIndex; | ||
} | ||
} |
@@ -1,1 +0,2 @@ | ||
// To be implemented in https://github.com/vaadin/web-components/issues/283 | ||
import './theme/lumo/vaadin-virtual-list.js'; | ||
export * from './src/vaadin-virtual-list.js'; |
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
79962
16.15%14
55.56%1928
16.57%74
3600%5
Infinity%