feat(virtual-scroll): adds JSX support

This commit is contained in:
Manu Mtz.-Almeida
2018-03-07 18:04:03 +01:00
parent a8b90a3eb1
commit dc8b363ea8
4 changed files with 50 additions and 11 deletions

View File

@ -3618,6 +3618,7 @@ declare global {
itemRender?: ItemRenderFn;
items?: any[];
nodeHeight?: NodeHeightFn;
renderer?: (item: any) => JSX.Element;
}
}
}

View File

@ -280,6 +280,11 @@ which is an expensive operation and should be avoided if possible.
#### renderer
## Attributes
#### approx-footer-height
@ -379,6 +384,11 @@ which is an expensive operation and should be avoided if possible.
#### renderer
## Methods
#### markDirty()

View File

@ -44,7 +44,7 @@ export type NodeHeightFn = (node: VirtualNode, index: number) => number;
export type HeaderFn = (item: any, index: number, items: any[]) => string | null;
export type ItemHeightFn = (item: any, index?: number) => number;
export type ItemRenderFn = (el: HTMLElement|null, cell: Cell, domIndex?: number) => HTMLElement;
export type DomRenderFn = (dom: VirtualNode[], height: number) => void;
export type DomRenderFn = (dom: VirtualNode[]) => void;
export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: Cell[], range: Range) {
// reset dom

View File

@ -13,7 +13,7 @@ import { Cell, DomRenderFn, HeaderFn, ItemHeightFn,
})
export class VirtualScroll {
private scrollEl: HTMLElement | null;
private scrollEl: HTMLIonScrollElement | null;
private range: Range = {offset: 0, length: 0};
private timerUpdate: any;
private heightIndex: Uint32Array;
@ -99,6 +99,7 @@ export class VirtualScroll {
*/
@Prop() items: any[];
@Prop() renderer: (item: any) => JSX.Element;
@Prop() nodeHeight: NodeHeightFn;
@Prop() itemHeight: ItemHeightFn;
@Prop() itemRender: ItemRenderFn;
@ -116,9 +117,11 @@ export class VirtualScroll {
console.error('virtual-scroll must be used inside ion-scroll/ion-content');
return;
}
this.calcDimensions();
this.calcCells();
this.updateState();
this.scrollEl.componentOnReady().then(() => {
this.calcDimensions();
this.calcCells();
this.updateState();
});
}
componentDidUpdate() {
@ -251,12 +254,14 @@ export class VirtualScroll {
// write DOM
if (this.itemRender) {
doRender(this.el, this.itemRender, this.virtualDom, this.updateCellHeight.bind(this));
if (this.heightChanged) {
this.el.style.height = this.totalHeight + 'px';
this.heightChanged = false;
}
} else if (this.domRender) {
this.domRender(this.virtualDom, this.totalHeight);
this.domRender(this.virtualDom);
} else if (this.renderer) {
(this.el as any).forceUpdate();
}
if (this.heightChanged) {
this.el.style.height = this.totalHeight + 'px';
this.heightChanged = false;
}
}
@ -299,7 +304,6 @@ export class VirtualScroll {
const shouldEnable = !!(
this.scrollEl &&
this.cells &&
(this.itemRender || this.domRender) &&
this.viewportHeight > 1
);
if (shouldEnable !== this.isEnabled) {
@ -362,4 +366,28 @@ export class VirtualScroll {
this.enableListener(this, 'scroll', shouldListen, this.scrollEl);
}
}
render() {
const renderer = this.renderer;
if (renderer) {
return this.virtualDom.map((dom) => {
const item = renderer(dom.cell.value) as any;
const classes = ['virtual-item'];
if (!item.vattrs) {
item.vattrs = {};
}
item.vattrs.class += ' virtual-item';
if (!dom.visible) {
classes.push('virtual-loading');
}
item.vattrs.class += ' ' + classes.join(' ');
if (!item.vattrs.style) {
item.vattrs.style = {};
}
item.vattrs.style['transform'] = `translate3d(0,${dom.top}px,0)`;
return item;
});
}
return undefined;
}
}