Skip to content

Commit

Permalink
Merge branch 'homebound-team-add-item-size-prop'
Browse files Browse the repository at this point in the history
  • Loading branch information
petyosi committed Jun 1, 2021
2 parents 8b108b7 + 79a910e commit fee2757
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 7 deletions.
4 changes: 3 additions & 1 deletion src/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,9 @@ export const Items = React.memo(function VirtuosoItems({ showTopList = false }:
const itemContent = useEmitterValue('itemContent')
const groupContent = useEmitterValue('groupContent')
const trackItemSizes = useEmitterValue('trackItemSizes')
const itemSize = useEmitterValue('itemSize')

const ref = useChangedChildSizes(sizeRanges, trackItemSizes)
const ref = useChangedChildSizes(sizeRanges, itemSize, trackItemSizes)
const EmptyPlaceholder = useEmitterValue('EmptyPlaceholder')
const ScrollSeekPlaceholder = useEmitterValue('ScrollSeekPlaceholder') || DefaultScrollSeekPlaceholder
const ListComponent = useEmitterValue('ListComponent')!
Expand Down Expand Up @@ -418,6 +419,7 @@ export const { Component: List, usePublisher, useEmitterValue, useEmitter } = sy
computeItemKey: 'computeItemKey',
defaultItemHeight: 'defaultItemHeight',
fixedItemHeight: 'fixedItemHeight',
itemSize: 'itemSize',
scrollSeekConfiguration: 'scrollSeekConfiguration',
headerFooterTag: 'headerFooterTag',
data: 'data',
Expand Down
7 changes: 7 additions & 0 deletions src/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ export interface VirtuosoProps<D> extends Omit<ListProps, 'groupCounts' | 'group
*/
defaultItemHeight?: number

/**
* Allows customizing the height/width calculation of `Item` elements.
*
* The default implementation reads `el.offsetHeight` and `el.offsetWidth`.
*/
itemSize?: (el: HTMLElement, field: 'offsetHeight' | 'offsetWidth') => number

/**
* Can be used to improve performance if the rendered items are of known size.
* Setting it causes the component to skip item measurements.
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/useChangedChildSizes.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { SizeRange } from '../sizeSystem'
import { SizeFunction, SizeRange } from '../sizeSystem'
import useSize from './useSize'

export default function useChangedChildSizes(callback: (ranges: SizeRange[]) => void, enabled: boolean) {
export default function useChangedChildSizes(callback: (ranges: SizeRange[]) => void, itemSize: SizeFunction, enabled: boolean) {
return useSize((el: HTMLElement) => {
const ranges = getChangedChildSizes(el.children, 'offsetHeight')
const ranges = getChangedChildSizes(el.children, itemSize, 'offsetHeight')
if (ranges !== null) {
callback(ranges)
}
}, enabled)
}

function getChangedChildSizes(children: HTMLCollection, field: 'offsetHeight' | 'offsetWidth') {
function getChangedChildSizes(children: HTMLCollection, itemSize: SizeFunction, field: 'offsetHeight' | 'offsetWidth') {
const length = children.length

if (length === 0) {
Expand All @@ -28,7 +28,7 @@ function getChangedChildSizes(children: HTMLCollection, field: 'offsetHeight' |

const index = parseInt(child.dataset.index!)
const knownSize = parseInt(child.dataset.knownSize!)
const size = child[field]
const size = itemSize(child, field)

if (size === 0) {
throw new Error('Zero-sized element, this should not happen')
Expand Down
3 changes: 2 additions & 1 deletion src/listSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const featureGroup1System = u.system(

export const listSystem = u.system(
([
{ totalCount, sizeRanges, fixedItemSize, defaultItemSize, trackItemSizes, data, firstItemIndex, groupIndices },
{ totalCount, sizeRanges, fixedItemSize, defaultItemSize, trackItemSizes, itemSize, data, firstItemIndex, groupIndices },
{ initialTopMostItemIndex, scrolledToInitialItem },
domIO,
followOutput,
Expand Down Expand Up @@ -79,6 +79,7 @@ export const listSystem = u.system(
listState,
scrollToIndex,
trackItemSizes,
itemSize,
groupIndices,

// exported from stateFlagsSystem
Expand Down
6 changes: 6 additions & 0 deletions src/sizeSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ export function hasGroups(sizes: SizeState) {
}

type OptionalNumber = number | undefined

/** Calculates the height of `el`, which will be the `Item` element in the DOM. */
export type SizeFunction = (el: HTMLElement, field: 'offsetHeight' | 'offsetWidth') => number

export const sizeSystem = u.system(
() => {
const sizeRanges = u.stream<SizeRange[]>()
Expand All @@ -236,6 +240,7 @@ export const sizeSystem = u.system(
const groupIndices = u.statefulStream([] as number[])
const fixedItemSize = u.statefulStream<OptionalNumber>(undefined)
const defaultItemSize = u.statefulStream<OptionalNumber>(undefined)
const itemSize = u.statefulStream<SizeFunction>((el, field) => el[field])
const data = u.statefulStream<Data>(undefined)
const initial = initialSizeState()

Expand Down Expand Up @@ -384,6 +389,7 @@ export const sizeSystem = u.system(
sizes,
listRefresh,
trackItemSizes,
itemSize,
}
},
[],
Expand Down

0 comments on commit fee2757

Please sign in to comment.