Skip to content

Commit

Permalink
fix: align to bottom does not blink with defaultItemHeight
Browse files Browse the repository at this point in the history
  • Loading branch information
petyosi committed Feb 24, 2024
1 parent 57928bd commit eb404d9
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 12 deletions.
19 changes: 18 additions & 1 deletion examples/align-to-bottom.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react'
import { Virtuoso } from '../src'
import { Virtuoso, TableVirtuoso } from '../src'

export function Example() {
const [total, setTotal] = React.useState(10)
Expand All @@ -22,3 +22,20 @@ export function Example() {
</div>
)
}

export function TableExample() {
return (
<TableVirtuoso
alignToBottom={true}
style={{ height: 400, border: '1px solid red' }}
data={['foo', 'bar', 'baz']}
itemContent={(index, string) => (
<>
<td>{index}</td>
<td style={{ width: 150 }}>{string}</td>
<td>{string}</td>
</>
)}
/>
)
}
4 changes: 2 additions & 2 deletions src/TableVirtuoso.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
}, [ctx, viewportHeight, fixedItemHeight])

return (
<div style={viewportStyle} ref={viewportRef} data-viewport-type="element">
<div style={viewportStyle(false)} ref={viewportRef} data-viewport-type="element">
{children}
</div>
)
Expand All @@ -203,7 +203,7 @@ const WindowViewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }
}, [ctx, windowViewportRect, fixedItemHeight])

return (
<div ref={viewportRef} style={viewportStyle} data-viewport-type="window">
<div ref={viewportRef} style={viewportStyle(false)} data-viewport-type="window">
{children}
</div>
)
Expand Down
17 changes: 10 additions & 7 deletions src/Virtuoso.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ const Items = /*#__PURE__*/ React.memo(function VirtuosoItems({ showTopList = fa
const computeItemKey = useEmitterValue('computeItemKey')
const isSeeking = useEmitterValue('isSeeking')
const hasGroups = useEmitterValue('groupIndices').length > 0
const paddingTopAddition = useEmitterValue('paddingTopAddition')
const alignToBottom = useEmitterValue('alignToBottom')
const scrolledToInitialItem = useEmitterValue('scrolledToInitialItem')

const containerStyle: React.CSSProperties = showTopList
? {}
: {
boxSizing: 'border-box',
paddingTop: listState.offsetTop + paddingTopAddition,
paddingTop: listState.offsetTop,
paddingBottom: listState.offsetBottom,
marginTop: deviation,
marginTop: deviation !== 0 ? deviation : alignToBottom ? 'auto' : 0,
...(scrolledToInitialItem ? {} : { visibility: 'hidden' }),
}

Expand Down Expand Up @@ -194,12 +194,13 @@ export const scrollerStyle: React.CSSProperties = {
WebkitOverflowScrolling: 'touch',
}

export const viewportStyle: React.CSSProperties = {
export const viewportStyle: (alignToBottom: boolean) => React.CSSProperties = (alignToBottom) => ({
width: '100%',
height: '100%',
position: 'absolute',
top: 0,
}
...(alignToBottom ? { display: 'flex', flexDirection: 'column' } : {}),
})

const topItemListStyle: React.CSSProperties = {
width: '100%',
Expand Down Expand Up @@ -325,6 +326,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
const ctx = React.useContext(VirtuosoMockContext)
const viewportHeight = usePublisher('viewportHeight')
const fixedItemHeight = usePublisher('fixedItemHeight')
const alignToBottom = useEmitterValue('alignToBottom')
const viewportRef = useSize(u.compose(viewportHeight, (el) => correctItemSize(el, 'height')))

React.useEffect(() => {
Expand All @@ -335,7 +337,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
}, [ctx, viewportHeight, fixedItemHeight])

return (
<div style={viewportStyle} ref={viewportRef} data-viewport-type="element">
<div style={viewportStyle(alignToBottom)} ref={viewportRef} data-viewport-type="element">
{children}
</div>
)
Expand All @@ -347,6 +349,7 @@ const WindowViewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }
const fixedItemHeight = usePublisher('fixedItemHeight')
const customScrollParent = useEmitterValue('customScrollParent')
const viewportRef = useWindowViewportRectRef(windowViewportRect, customScrollParent)
const alignToBottom = useEmitterValue('alignToBottom')

React.useEffect(() => {
if (ctx) {
Expand All @@ -356,7 +359,7 @@ const WindowViewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }
}, [ctx, windowViewportRect, fixedItemHeight])

return (
<div ref={viewportRef} style={viewportStyle} data-viewport-type="window">
<div ref={viewportRef} style={viewportStyle(alignToBottom)} data-viewport-type="window">
{children}
</div>
)
Expand Down
4 changes: 2 additions & 2 deletions src/VirtuosoGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const Viewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }) => {
}, [ctx, viewportDimensions, itemDimensions])

return (
<div style={viewportStyle} ref={viewportRef}>
<div style={viewportStyle(false)} ref={viewportRef}>
{children}
</div>
)
Expand All @@ -180,7 +180,7 @@ const WindowViewport: React.FC<React.PropsWithChildren<unknown>> = ({ children }
}, [ctx, windowViewportRect, itemDimensions])

return (
<div ref={viewportRef} style={viewportStyle}>
<div ref={viewportRef} style={viewportStyle(false)}>
{children}
</div>
)
Expand Down
1 change: 1 addition & 0 deletions src/alignToBottomSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const alignToBottomSystem = u.system(
([{ viewportHeight }, { totalListHeight }]) => {
const alignToBottom = u.statefulStream(false)

// keep this for the table component only
const paddingTopAddition = u.statefulStreamFromEmitter(
u.pipe(
u.combineLatest(alignToBottom, viewportHeight, totalListHeight),
Expand Down

0 comments on commit eb404d9

Please sign in to comment.