mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
feat(virtual-scroll): adds JSX support
This commit is contained in:
1
packages/core/src/components.d.ts
vendored
1
packages/core/src/components.d.ts
vendored
@ -3618,6 +3618,7 @@ declare global {
|
|||||||
itemRender?: ItemRenderFn;
|
itemRender?: ItemRenderFn;
|
||||||
items?: any[];
|
items?: any[];
|
||||||
nodeHeight?: NodeHeightFn;
|
nodeHeight?: NodeHeightFn;
|
||||||
|
renderer?: (item: any) => JSX.Element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -280,6 +280,11 @@ which is an expensive operation and should be avoided if possible.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### renderer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Attributes
|
## Attributes
|
||||||
|
|
||||||
#### approx-footer-height
|
#### approx-footer-height
|
||||||
@ -379,6 +384,11 @@ which is an expensive operation and should be avoided if possible.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### renderer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
#### markDirty()
|
#### markDirty()
|
||||||
|
@ -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 HeaderFn = (item: any, index: number, items: any[]) => string | null;
|
||||||
export type ItemHeightFn = (item: any, index?: number) => number;
|
export type ItemHeightFn = (item: any, index?: number) => number;
|
||||||
export type ItemRenderFn = (el: HTMLElement|null, cell: Cell, domIndex?: number) => HTMLElement;
|
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) {
|
export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: Cell[], range: Range) {
|
||||||
// reset dom
|
// reset dom
|
||||||
|
@ -13,7 +13,7 @@ import { Cell, DomRenderFn, HeaderFn, ItemHeightFn,
|
|||||||
})
|
})
|
||||||
export class VirtualScroll {
|
export class VirtualScroll {
|
||||||
|
|
||||||
private scrollEl: HTMLElement | null;
|
private scrollEl: HTMLIonScrollElement | null;
|
||||||
private range: Range = {offset: 0, length: 0};
|
private range: Range = {offset: 0, length: 0};
|
||||||
private timerUpdate: any;
|
private timerUpdate: any;
|
||||||
private heightIndex: Uint32Array;
|
private heightIndex: Uint32Array;
|
||||||
@ -99,6 +99,7 @@ export class VirtualScroll {
|
|||||||
*/
|
*/
|
||||||
@Prop() items: any[];
|
@Prop() items: any[];
|
||||||
|
|
||||||
|
@Prop() renderer: (item: any) => JSX.Element;
|
||||||
@Prop() nodeHeight: NodeHeightFn;
|
@Prop() nodeHeight: NodeHeightFn;
|
||||||
@Prop() itemHeight: ItemHeightFn;
|
@Prop() itemHeight: ItemHeightFn;
|
||||||
@Prop() itemRender: ItemRenderFn;
|
@Prop() itemRender: ItemRenderFn;
|
||||||
@ -116,9 +117,11 @@ export class VirtualScroll {
|
|||||||
console.error('virtual-scroll must be used inside ion-scroll/ion-content');
|
console.error('virtual-scroll must be used inside ion-scroll/ion-content');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.scrollEl.componentOnReady().then(() => {
|
||||||
this.calcDimensions();
|
this.calcDimensions();
|
||||||
this.calcCells();
|
this.calcCells();
|
||||||
this.updateState();
|
this.updateState();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
@ -251,13 +254,15 @@ export class VirtualScroll {
|
|||||||
// write DOM
|
// write DOM
|
||||||
if (this.itemRender) {
|
if (this.itemRender) {
|
||||||
doRender(this.el, this.itemRender, this.virtualDom, this.updateCellHeight.bind(this));
|
doRender(this.el, this.itemRender, this.virtualDom, this.updateCellHeight.bind(this));
|
||||||
|
} else if (this.domRender) {
|
||||||
|
this.domRender(this.virtualDom);
|
||||||
|
} else if (this.renderer) {
|
||||||
|
(this.el as any).forceUpdate();
|
||||||
|
}
|
||||||
if (this.heightChanged) {
|
if (this.heightChanged) {
|
||||||
this.el.style.height = this.totalHeight + 'px';
|
this.el.style.height = this.totalHeight + 'px';
|
||||||
this.heightChanged = false;
|
this.heightChanged = false;
|
||||||
}
|
}
|
||||||
} else if (this.domRender) {
|
|
||||||
this.domRender(this.virtualDom, this.totalHeight);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateCellHeight(cell: Cell, node: HTMLStencilElement | HTMLElement) {
|
private updateCellHeight(cell: Cell, node: HTMLStencilElement | HTMLElement) {
|
||||||
@ -299,7 +304,6 @@ export class VirtualScroll {
|
|||||||
const shouldEnable = !!(
|
const shouldEnable = !!(
|
||||||
this.scrollEl &&
|
this.scrollEl &&
|
||||||
this.cells &&
|
this.cells &&
|
||||||
(this.itemRender || this.domRender) &&
|
|
||||||
this.viewportHeight > 1
|
this.viewportHeight > 1
|
||||||
);
|
);
|
||||||
if (shouldEnable !== this.isEnabled) {
|
if (shouldEnable !== this.isEnabled) {
|
||||||
@ -362,4 +366,28 @@ export class VirtualScroll {
|
|||||||
this.enableListener(this, 'scroll', shouldListen, this.scrollEl);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user