Skip to content

Commit

Permalink
feat: add list
Browse files Browse the repository at this point in the history
  • Loading branch information
ryuever committed Dec 28, 2024
1 parent ffdae7b commit ff7672e
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 6 deletions.
6 changes: 4 additions & 2 deletions examples/ReactNativeListPlayground/app/(tabs)/List.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useCallback, useMemo, useRef } from 'react';
import { List, ScrollView } from '@infinite-list/react-native';
import { List } from '@infinite-list/list';
import { ScrollView } from '@infinite-list/scroller';
import {
// NativeScrollEvent,
// NativeSyntheticEvent,
ScrollView as NativeScrollView,
Text,
View,
} from 'react-native';
Expand All @@ -15,7 +17,7 @@ const buildData = (count: number, startIndex = 0) =>

export default () => {
const data = useMemo(() => buildData(10000), []);
const scrollViewRef = useRef<ScrollView>(null);
const scrollViewRef = useRef<NativeScrollView>(null);

const renderItem = useCallback((props: { item }) => {
const { item } = props;
Expand Down
3 changes: 2 additions & 1 deletion examples/ReactNativeListPlayground/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,6 @@ import MasonryList from './MasonryList';
import { Text } from 'react-native';

export default () => {
return <MasonryList />;
// return <MasonryList />;
return <List />;
};
43 changes: 42 additions & 1 deletion examples/ReactNativeListPlayground/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,28 @@ const scrollerPkg = JSON.parse(
const scrollerModules = Object.keys({
...scrollerPkg.dependencies,
});
const listPkg = JSON.parse(
fs.readFileSync(path.join(root, 'ui', 'list', 'package.json'), 'utf8')
);
const listModules = Object.keys({
...listPkg.dependencies,
});
const groupPkg = JSON.parse(
fs.readFileSync(path.join(root, 'ui', 'group', 'package.json'), 'utf8')
);
const groupModules = Object.keys({
...groupPkg.dependencies,
});

const extraModules = []
.concat(reactNativeModules, dataModelModules, masonryModules, scrollerModules)
.concat(
reactNativeModules,
dataModelModules,
masonryModules,
scrollerModules,
listModules,
groupModules
)
.reduce((acc, name) => {
acc[name] = path.join(root, 'packages', 'data-model', 'node_modules', name);
return acc;
Expand All @@ -104,13 +123,27 @@ config.resolver.extraNodeModules = {
'src'
),
'@infinite-list/data-model': path.join(root, 'packages', 'data-model', 'src'),
'@infinite-list/list': path.join(root, 'ui', 'list', 'src'),
'@infinite-list/group': path.join(root, 'ui', 'group', 'src'),
'@infinite-list/masonry': path.join(root, 'ui', 'masonry', 'src'),
'@infinite-list/group-dimensions': path.join(
root,
'model',
'group-dimensions',
'src'
),
'@infinite-list/masonry-dimensions': path.join(
root,
'model',
'masonry-dimensions',
'src'
),
'@infinite-list/list-dimensions': path.join(
root,
'model',
'list-dimensions',
'src'
),
'@infinite-list/scroller': path.join(root, 'ui', 'scroller', 'src'),
'@infinite-list/viewable': path.join(root, 'core', 'viewable', 'src'),
'@infinite-list/base-dimensions': path.join(
Expand All @@ -137,12 +170,20 @@ config.watchFolders = [
path.join(root, 'packages', 'react-native', 'node_modules'),
path.join(root, 'packages', 'data-model', 'src'),
path.join(root, 'packages', 'data-model', 'node_modules'),
path.join(root, 'ui', 'group', 'src'),
path.join(root, 'ui', 'group', 'node_modules'),
path.join(root, 'ui', 'list', 'src'),
path.join(root, 'ui', 'list', 'node_modules'),
path.join(root, 'ui', 'masonry', 'src'),
path.join(root, 'ui', 'masonry', 'node_modules'),
path.join(root, 'ui', 'scroller', 'src'),
path.join(root, 'ui', 'scroller', 'node_modules'),
path.join(root, 'model', 'masonry-dimensions', 'src'),
path.join(root, 'model', 'masonry-dimensions', 'node_modules'),
path.join(root, 'model', 'group-dimensions', 'src'),
path.join(root, 'model', 'group-dimensions', 'node_modules'),
path.join(root, 'model', 'list-dimensions', 'src'),
path.join(root, 'model', 'list-dimensions', 'node_modules'),
path.join(root, 'core', 'viewable', 'src'),
path.join(root, 'core', 'viewable', 'node_modules'),
path.join(root, 'core', 'base-dimensions', 'src'),
Expand Down
2 changes: 2 additions & 0 deletions examples/ReactNativeListPlayground/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"@infinite-list/react-native": ["../../packages/react-native/src"],
"@infinite-list/masonry": ["../../ui/masonry/src/react-native"],
"@infinite-list/scroller": ["../../ui/scroller/src/react-native"],
"@infinite-list/group": ["../../ui/group/src/react-native"],
"@infinite-list/list": ["../../ui/list/src/react-native"],
}
},
"include": [
Expand Down
41 changes: 39 additions & 2 deletions ui/list/src/react-native/List.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { useEffect, useMemo, useState, useRef, useContext } from 'react';
import {
useEffect,
useMemo,
useState,
useRef,
useContext,
useCallback,
} from 'react';
import {
View,
ViewStyle,
Expand Down Expand Up @@ -51,6 +58,31 @@ const List = <ItemT extends GenericItemT>(props: ListProps<ItemT>) => {
const offsetRef = useRef(0);
const tsRef = useRef(Date.now());

/**
* Trigger list render after initialization or content will be blank
*/
const onLayoutHandler = useCallback(() => {
const scrollMetrics = contextValues
.getScrollHelper()
.getScrollEventMetrics();
const timestamp = Date.now();
const offset = scrollMetrics.contentOffset.y;

const dOffset = offset - offsetRef.current;
const dt = timestamp - tsRef.current;
const velocity = dOffset / dt;

offsetRef.current = offset;
tsRef.current = timestamp;

listModel.updateScrollMetrics({
offset,
visibleLength: scrollMetrics.layoutMeasurement.height,
contentLength: scrollMetrics.contentSize.height,
velocity,
});
}, []);

useEffect(
() =>
contextValues
Expand Down Expand Up @@ -83,7 +115,12 @@ const List = <ItemT extends GenericItemT>(props: ListProps<ItemT>) => {
if (recycleEnabled) {
const nextState = state as RecycleStateResult<ItemT>;
return (
<View id={id} ref={listRef} style={style.container}>
<View
id={id}
ref={listRef}
style={style.container}
onLayout={onLayoutHandler}
>
{nextState.recycleState.map((data) => (
<RecycleItem
key={data.key}
Expand Down

0 comments on commit ff7672e

Please sign in to comment.