Checkpoint Layout.List

This commit is contained in:
Eric Bailey
2025-09-24 11:05:01 -05:00
parent e44a022226
commit 391a1d4be3
3 changed files with 59 additions and 87 deletions
+17
View File
@@ -23,6 +23,11 @@ import {
import {useDialogContext} from '#/components/Dialog'
import {CENTER_COLUMN_OFFSET, SCROLLBAR_OFFSET} from '#/components/Layout/const'
import {ScrollbarOffsetContext} from '#/components/Layout/context'
import {
List as BaseList,
type ListItem,
type ListProps,
} from '#/components/List'
export * from '#/components/Layout/const'
export * as Header from '#/components/Layout/Header'
@@ -223,3 +228,15 @@ const WebCenterBorders = memo(function LayoutWebCenterBorders() {
/>
) : null
})
export function List<Item extends ListItem>(props: ListProps<Item>) {
return (
<BaseList<Item>
{...props}
renderItem={item => {
return <Center>{props.renderItem!(item)}</Center>
}}
style={[a.h_full_vh, props.style]}
/>
)
}
+4 -2
View File
@@ -27,7 +27,9 @@ export {
export type ListRef<Item extends {key: string}> =
React.MutableRefObject<FlatList<Item> | null>
type ListProps<Item extends {key: string}> = Omit<
export type ListItem = {key: string}
export type ListProps<Item extends ListItem> = Omit<
FlatListProps<Item>,
| 'onScroll'
| 'onScrollBeginDrag'
@@ -87,7 +89,7 @@ type ListProps<Item extends {key: string}> = Omit<
onScrolledDownChange?: (isScrolledDown: boolean) => void
}
export const List = forwardRef(function List<Item extends {key: string}>(
export const List = forwardRef(function List<Item extends ListItem>(
{...props}: ListProps<Item>,
ref: React.Ref<FlatList<Item>>,
) {
+38 -85
View File
@@ -1,13 +1,9 @@
import {useState} from 'react'
import {View} from 'react-native'
import {runOnJS} from 'react-native-reanimated'
import {ScrollProvider} from '#/lib/ScrollContext'
import {List as OldList} from '#/view/com/util/List'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Layout from '#/components/Layout'
import {List, ListScrollProvider, useListScrollHandler} from '#/components/List'
import {ListScrollProvider, useListScrollHandler} from '#/components/List'
import {Text} from '#/components/Typography'
export function StorybookLists() {
@@ -36,21 +32,8 @@ type Item =
const log = (msg: any) => console.log(msg)
function Header() {
return (
<Layout.Header.Outer>
<Layout.Header.BackButton />
<Layout.Header.Content>
<Layout.Header.TitleText>Storybook</Layout.Header.TitleText>
</Layout.Header.Content>
<Layout.Header.Slot />
</Layout.Header.Outer>
)
}
export function Inner() {
const t = useTheme()
const [old, setOld] = useState<boolean>(false)
const onScrollWorklet = useListScrollHandler(e => {
'worklet'
runOnJS(log)(`scroll ${e.contentOffset.y}`)
@@ -74,73 +57,43 @@ export function Inner() {
})
return (
<View style={[]}>
<View
style={[a.fixed, a.w_full, a.py_sm, a.px_xl, a.align_center, a.z_10]}>
<Button
label="Toggle Old/New List"
onPress={() => setOld(v => !v)}
size="tiny"
color="primary_subtle">
<ButtonText>
{old ? 'Testing old List' : 'Testing new List'}
</ButtonText>
</Button>
</View>
<ListScrollProvider onScroll={onScrollWorklet}>
<Layout.List<Item>
data={items}
stickyHeaderIndices={[1]}
renderItem={({item, index}) => {
if (item.type === 'header') {
return (
<Layout.Header.Outer>
<Layout.Header.BackButton />
<Layout.Header.Content>
<Layout.Header.TitleText>Storybook</Layout.Header.TitleText>
</Layout.Header.Content>
<Layout.Header.Slot />
</Layout.Header.Outer>
)
}
if (item.type === 'spacer') {
return <View style={[t.atoms.bg_contrast_50, {height: 100}]} />
}
{!old ? (
<ListScrollProvider onScroll={onScrollWorklet}>
<List<Item>
data={items}
onScrolledDownChange={scrolledDown => {
console.log(`Scrolled down: ${scrolledDown}`)
}}
stickyHeaderIndices={[1]}
renderItem={({item, index}) => {
if (item.type === 'header') {
return <Header />
}
if (item.type === 'spacer') {
return <View style={[t.atoms.bg_contrast_50, {height: 100}]} />
}
return (
<Layout.Center>
<View
style={[
a.px_md,
a.align_center,
a.justify_center,
{height: 100},
index % 2 === 0 ? t.atoms.bg_contrast_25 : t.atoms.bg,
]}>
<Text>{item.title}</Text>
</View>
</Layout.Center>
)
}}
style={[a.h_full_vh]}
/>
</ListScrollProvider>
) : (
<ScrollProvider onScroll={onScrollWorklet}>
<OldList
data={items}
keyExtractor={item => item.key}
headerOffset={100}
onScrolledDownChange={scrolledDown => {
console.log(`Scrolled down: ${scrolledDown}`)
}}
renderItem={({item}) => (
<View style={[a.p_md, a.border_b]}>
<Text>{item.title}</Text>
</View>
)}
style={[a.debug]}
desktopFixedHeight
/>
</ScrollProvider>
)}
</View>
return (
<View
style={[
a.px_md,
a.align_center,
a.justify_center,
{height: 100},
index % 2 === 0 ? t.atoms.bg_contrast_25 : t.atoms.bg,
]}>
<Text>{item.title}</Text>
</View>
)
}}
onScrolledDownChange={scrolledDown => {
console.log(`Scrolled down: ${scrolledDown}`)
}}
/>
</ListScrollProvider>
)
}