New Web Layout (#2126)
* Rip out virtualization on the web * Screw around with layout * onEndReached * scrollToOffset * Fix background * onScroll * Shell bars * More scroll * Fixes * position: sticky * Clean up 1 * Clean up 2 * Undo PagerWithHeader changes and fork it * Trim down both versions * Cleanup 3 * Memoize, lint * Don't scroll away modal or lightbox * Add content-visibility for rows * Fix composer * Fix types * Fix borked scroll animation * Fixes to layout * More FlatList parity * Layout fixes * Fix more layout * More layout * More layouts * Fix profile layout * Remove onScroll * Display: none inactive pages * Add an intermediate List component * Fix type * Add onScrolledDownChange * Port pager to use onScrolledDownChange * Fix on mobile * Don't pass down onScroll (replacement TBD) * Remove resetMainScroll * Replace onMainScroll with MainScrollProvider * Hook ScrollProvider to pager * Fix the remaining special case * Optimize a bit * Enforce that onScroll cannot be passed * Keep value updated even if no handler * Also memo it * Move the fork to List.web * Add scroll handler * Consolidate List props a bit * More stuff * Rm unused * Simplify * Make isScrolledDown work * Oops * Fixes * Hook up context scroll handlers * Scroll restore for tabs * Route scroll restoration POC * Fix some issues with restoration * Remove bad idea * Fix pager scroll restoration * Undo accidental locale changes * onContentSizeChange * Scroll to post * Better positioning * Layout fixes * Factor out navigation stuff * Cleanup * Oops * Cleanup * Fixes and types * Naming etc * Fix crash * Match FL semantics * Snap the header scroll on the web * Add body scroll lock * Scroll to top on search * Fix types * Typos * Fix Safari overflow * Fix search positioning * Add border * Patch react navigation * Revert "Patch react navigation" This reverts commit 62516ed9c20410d166e1582b43b656c819495ddc. * fixes * scroll * scrollbar * cleanup unrelated * undo unrel * flatter * Fix css * twk
This commit is contained in:
parent
cd02922b03
commit
f015229acf
35 changed files with 849 additions and 97 deletions
|
|
@ -1,10 +1,12 @@
|
|||
import React from 'react'
|
||||
import {flushSync} from 'react-dom'
|
||||
import {View} from 'react-native'
|
||||
import {s} from 'lib/styles'
|
||||
|
||||
export interface RenderTabBarFnProps {
|
||||
selectedPage: number
|
||||
onSelect?: (index: number) => void
|
||||
tabBarAnchor?: JSX.Element
|
||||
}
|
||||
export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
|
||||
|
||||
|
|
@ -27,6 +29,8 @@ export const Pager = React.forwardRef(function PagerImpl(
|
|||
ref,
|
||||
) {
|
||||
const [selectedPage, setSelectedPage] = React.useState(initialPage)
|
||||
const scrollYs = React.useRef<Array<number | null>>([])
|
||||
const anchorRef = React.useRef(null)
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
setPage: (index: number) => setSelectedPage(index),
|
||||
|
|
@ -34,11 +38,36 @@ export const Pager = React.forwardRef(function PagerImpl(
|
|||
|
||||
const onTabBarSelect = React.useCallback(
|
||||
(index: number) => {
|
||||
setSelectedPage(index)
|
||||
onPageSelected?.(index)
|
||||
onPageSelecting?.(index)
|
||||
const scrollY = window.scrollY
|
||||
// We want to determine if the tabbar is already "sticking" at the top (in which
|
||||
// case we should preserve and restore scroll), or if it is somewhere below in the
|
||||
// viewport (in which case a scroll jump would be jarring). We determine this by
|
||||
// measuring where the "anchor" element is (which we place just above the tabbar).
|
||||
let anchorTop = anchorRef.current
|
||||
? (anchorRef.current as Element).getBoundingClientRect().top
|
||||
: -scrollY // If there's no anchor, treat the top of the page as one.
|
||||
const isSticking = anchorTop <= 5 // This would be 0 if browser scrollTo() was reliable.
|
||||
|
||||
if (isSticking) {
|
||||
scrollYs.current[selectedPage] = window.scrollY
|
||||
} else {
|
||||
scrollYs.current[selectedPage] = null
|
||||
}
|
||||
flushSync(() => {
|
||||
setSelectedPage(index)
|
||||
onPageSelected?.(index)
|
||||
onPageSelecting?.(index)
|
||||
})
|
||||
if (isSticking) {
|
||||
const restoredScrollY = scrollYs.current[index]
|
||||
if (restoredScrollY != null) {
|
||||
window.scrollTo(0, restoredScrollY)
|
||||
} else {
|
||||
window.scrollTo(0, scrollY + anchorTop)
|
||||
}
|
||||
}
|
||||
},
|
||||
[setSelectedPage, onPageSelected, onPageSelecting],
|
||||
[selectedPage, setSelectedPage, onPageSelected, onPageSelecting],
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
@ -46,21 +75,11 @@ export const Pager = React.forwardRef(function PagerImpl(
|
|||
{tabBarPosition === 'top' &&
|
||||
renderTabBar({
|
||||
selectedPage,
|
||||
tabBarAnchor: <View ref={anchorRef} />,
|
||||
onSelect: onTabBarSelect,
|
||||
})}
|
||||
{React.Children.map(children, (child, i) => (
|
||||
<View
|
||||
style={
|
||||
selectedPage === i
|
||||
? s.flex1
|
||||
: {
|
||||
position: 'absolute',
|
||||
pointerEvents: 'none',
|
||||
// @ts-ignore web-only
|
||||
visibility: 'hidden',
|
||||
}
|
||||
}
|
||||
key={`page-${i}`}>
|
||||
<View style={selectedPage === i ? s.flex1 : s.hidden} key={`page-${i}`}>
|
||||
{child}
|
||||
</View>
|
||||
))}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue