diff --git a/src/TableVirtuoso.tsx b/src/TableVirtuoso.tsx index 8043fec47..1bf741a4c 100644 --- a/src/TableVirtuoso.tsx +++ b/src/TableVirtuoso.tsx @@ -79,8 +79,63 @@ const DefaultFillerRow = ({ height }: { height: number }) => ( const ITEM_STYLE = { overflowAnchor: 'none' } as const -const Items = /*#__PURE__*/ React.memo(function VirtuosoItems() { +const Items = /*#__PURE__*/ React.memo(function VirtuosoItems({ showTopList = false }: { showTopList?: boolean }) { const listState = useEmitterValue('listState') + const computeItemKey = useEmitterValue('computeItemKey') + const firstItemIndex = useEmitterValue('firstItemIndex') + const isSeeking = useEmitterValue('isSeeking') + const ScrollSeekPlaceholder = useEmitterValue('ScrollSeekPlaceholder') || DefaultScrollSeekPlaceholder + const context = useEmitterValue('context') + const TableRowComponent = useEmitterValue('TableRowComponent')! + const fixedHeaderHeight = useEmitterValue('fixedHeaderHeight') + const itemContent = useEmitterValue('itemContent') + + const topItemOffsets = (showTopList ? listState.topItems : []).reduce((acc, item, index) => { + if (index === 0) { + acc.push(item.size) + } else { + acc.push(acc[index - 1] + item.size) + } + return acc + }, []) + + const items = (showTopList ? listState.topItems : listState.items).map((item) => { + const index = item.originalIndex! + const key = computeItemKey(index + firstItemIndex, item.data, context) + const offsetTop = showTopList ? (index === 0 ? 0 : topItemOffsets[index - 1]) : 0 + + if (isSeeking) { + return ( + + ) + } + return ( + + {itemContent(item.index, item.data, context)} + + ) + }) + + return <>{items} +}) + +const TableBody = /*#__PURE__*/ React.memo(function TableVirtuosoBody() { + const listState = useEmitterValue('listState') + const showTopList = useEmitterValue('topItemsIndexes').length > 0 const sizeRanges = usePublisher('sizeRanges') const useWindowScroll = useEmitterValue('useWindowScroll') const customScrollParent = useEmitterValue('customScrollParent') @@ -88,7 +143,6 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems() { const _scrollContainerStateCallback = usePublisher('scrollContainerState') const scrollContainerStateCallback = customScrollParent || useWindowScroll ? windowScrollContainerStateCallback : _scrollContainerStateCallback - const itemContent = useEmitterValue('itemContent') const trackItemSizes = useEmitterValue('trackItemSizes') const itemSize = useEmitterValue('itemSize') const log = useEmitterValue('log') @@ -113,14 +167,9 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems() { } }) const EmptyPlaceholder = useEmitterValue('EmptyPlaceholder') - const ScrollSeekPlaceholder = useEmitterValue('ScrollSeekPlaceholder') || DefaultScrollSeekPlaceholder const FillerRow = useEmitterValue('FillerRow') || DefaultFillerRow const TableBodyComponent = useEmitterValue('TableBodyComponent')! - const TableRowComponent = useEmitterValue('TableRowComponent')! - const computeItemKey = useEmitterValue('computeItemKey') - const isSeeking = useEmitterValue('isSeeking') const paddingTopAddition = useEmitterValue('paddingTopAddition') - const firstItemIndex = useEmitterValue('firstItemIndex') const statefulTotalCount = useEmitterValue('statefulTotalCount') const context = useEmitterValue('context') @@ -128,47 +177,20 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems() { return } - const paddingTop = listState.offsetTop + paddingTopAddition + deviation + const topItemsSize = (showTopList ? listState.topItems : []).reduce((acc, item) => acc + item.size, 0) + + const paddingTop = listState.offsetTop + paddingTopAddition + deviation - topItemsSize const paddingBottom = listState.offsetBottom const paddingTopEl = paddingTop > 0 ? : null const paddingBottomEl = paddingBottom > 0 ? : null - const items = listState.items.map((item) => { - const index = item.originalIndex! - const key = computeItemKey(index + firstItemIndex, item.data, context) - - if (isSeeking) { - return ( - - ) - } - return ( - - {itemContent(item.index, item.data, context)} - - ) - }) - return ( {paddingTopEl} - {items} + {showTopList && } + {paddingBottomEl} ) @@ -276,7 +298,7 @@ const TableRoot: React.FC = /*#__PURE__*/ React.memo(function Ta {theHead} - + {theFoot} diff --git a/src/component-interfaces/TableVirtuoso.ts b/src/component-interfaces/TableVirtuoso.ts index 30e37d696..e740befa5 100644 --- a/src/component-interfaces/TableVirtuoso.ts +++ b/src/component-interfaces/TableVirtuoso.ts @@ -17,7 +17,7 @@ import type { } from '../interfaces' import type { VirtuosoProps } from './Virtuoso' -export interface TableVirtuosoProps extends Omit, 'components' | 'headerFooterTag' | 'topItemCount'> { +export interface TableVirtuosoProps extends Omit, 'components' | 'headerFooterTag'> { /** * Use the `components` property for advanced customization of the elements rendered by the table. */ @@ -33,6 +33,11 @@ export interface TableVirtuosoProps extends Omit, 'com */ fixedFooterContent?: FixedFooterContent + /** + * Set the amount of items to remain fixed at the top of the table. + */ + topItemCount?: number + /** * The total amount of items to be rendered. */