diff --git a/README.md b/README.md index 25948ba..e5d3064 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ render( | 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. | | onItemsRendered | Function | | Callback invoked with information about the slice of rows/columns that were just rendered. It has the following signature: `({startIndex: number, stopIndex: number})`. | | onScroll | Function | | Callback invoked whenever the scroll offset changes within the inner scrollable region. It has the following signature: `(scrollTop: number, event: React.UIEvent)`. | +| renderWrapper | Function | | Responsible for rendering the wrapper given `outerProps: any, ref: (node: HTMLElement) => void, innerStyle: React.CSSProperties , items: React.ReactNode[]`.| *\* Width may only be a string when `scrollDirection` is `'vertical'`. Similarly, Height may only be a string if `scrollDirection` is `'horizontal'`* diff --git a/src/index.tsx b/src/index.tsx index 8368dd5..f96d2fd 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -50,8 +50,8 @@ interface StyleCache { } export interface ItemInfo { - index: number, - style: ItemStyle, + index: number, + style: ItemStyle, } export interface RenderedRows { @@ -73,8 +73,9 @@ export interface Props { style?: any, width?: number | string, onItemsRendered?({startIndex, stopIndex}: RenderedRows): void, - onScroll?(offset: number, event: React.UIEvent): void, + onScroll?(offset: number, event: React.UIEvent): void, renderItem(itemInfo: ItemInfo): React.ReactNode, + renderWrapper?(outerProps: any, ref: any, innerStyle: any, items: React.ReactNode[]): React.ReactElement, } export interface State { @@ -82,9 +83,20 @@ export interface State { scrollChangeReason: SCROLL_CHANGE_REASON, } +function defaultRenderWrapper(outerProps: any, ref: (node: HTMLElement) => void, innerStyle: React.CSSProperties , items: React.ReactNode[]) { + return ( +
+
+ {items} +
+
); +} + + export default class VirtualList extends React.PureComponent { static defaultProps = { overscanCount: 3, + renderWrapper: defaultRenderWrapper, scrollDirection: DIRECTION_VERTICAL, width: '100%', }; @@ -97,6 +109,7 @@ export default class VirtualList extends React.PureComponent { onItemsRendered: PropTypes.func, overscanCount: PropTypes.number, renderItem: PropTypes.func.isRequired, + renderWrapper: PropTypes.func, scrollOffset: PropTypes.number, scrollToIndex: PropTypes.number, scrollToAlignment: PropTypes.oneOf([ALIGN_AUTO, ALIGN_START, ALIGN_CENTER, ALIGN_END]), @@ -191,7 +204,7 @@ export default class VirtualList extends React.PureComponent { } } - handleScroll = (e: React.UIEvent) => { + handleScroll = (e: React.UIEvent) => { const {onScroll} = this.props; const offset = this.getNodeOffset(); @@ -273,6 +286,7 @@ export default class VirtualList extends React.PureComponent { height, overscanCount = 3, renderItem, + renderWrapper = defaultRenderWrapper, itemCount, itemSize, onItemsRendered, @@ -309,16 +323,15 @@ export default class VirtualList extends React.PureComponent { } } - return ( -
-
- {items} -
-
+ return renderWrapper( + { ...props, onScroll: this.handleScroll, style: { ...STYLE_WRAPPER, ...style, height, width } }, + this.getRef, + { ...STYLE_INNER, [sizeProp[scrollDirection]]: this.sizeAndPositionManager.getTotalSize() }, + items, ); } - private getRef = (node: HTMLDivElement): void => { + private getRef = (node: HTMLElement): void => { this.rootNode = node; } }