Skip to content

Commit 1c1ea50

Browse files
committed
fix the kitchen sink home page use flat list
1 parent 1fb6486 commit 1c1ea50

File tree

1 file changed

+68
-56
lines changed

1 file changed

+68
-56
lines changed

apps/kitchen-sink/app/index.tsx

Lines changed: 68 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import React, { useContext } from 'react';
2-
import { Pressable, ScrollView } from 'react-native';
3-
import { useRouter, usePathname } from 'expo-router';
41
import { Box } from '@/components/ui/box';
2+
import { Grid, GridItem } from '@/components/ui/grid';
53
import { Heading } from '@/components/ui/heading';
6-
import { VStack } from '@/components/ui/vstack';
7-
import { Text } from '@/components/ui/text';
8-
import { getAllComponents } from '@/utils/getComponents';
94
import { HStack } from '@/components/ui/hstack';
5+
import { ChevronRightIcon, Icon } from '@/components/ui/icon';
106
import { Image } from '@/components/ui/image';
11-
import { ColorModeContext } from './_layout';
12-
import { ChevronRightIcon } from '@/components/ui/icon';
13-
import { Icon } from '@/components/ui/icon';
14-
import { Grid, GridItem } from '@/components/ui/grid';
7+
import { Text } from '@/components/ui/text';
8+
import { VStack } from '@/components/ui/vstack';
9+
import { getAllComponents } from '@/utils/getComponents';
10+
import { usePathname, useRouter } from 'expo-router';
11+
import React, { useContext, useMemo } from 'react';
12+
import { FlatList, Pressable } from 'react-native';
1513
import { SafeAreaView } from 'react-native-safe-area-context';
14+
import { ColorModeContext } from './_layout';
1615

1716
const components = getAllComponents();
1817
const ComponentCard = ({ component, onPress }: any) => {
@@ -51,7 +50,7 @@ const ComponentCard = ({ component, onPress }: any) => {
5150
const Header = () => {
5251
const { colorMode }: any = useContext(ColorModeContext);
5352
return (
54-
<HStack className="flex-1 bg-background-50 w-full mx-auto justify-between">
53+
<HStack className="bg-background-50 w-full mx-auto justify-between">
5554
<VStack className="w-full md:max-w-[630px] lg:max-w-[400px] xl:max-w-[480px] mx-5 md:ml-8 mb-8 mt-10 lg:my-[44px] xl:ml-[80px] flex-1">
5655
<HStack
5756
className="rounded-full bg-background-0 py-4 px-5 mb-7 md:mb-9 lg:mb-[80px] xl:mb-[132px] items-center native:max-w-[250px] w-fit"
@@ -101,63 +100,76 @@ export default function ComponentList() {
101100
const handleComponentPress = (componentPath: string) => {
102101
// Use Expo Router's built-in navigation state check
103102
const targetPath = `components/${componentPath}`;
104-
103+
105104
// Prevent navigation if we're already on the target path or if navigation is in progress
106105
if (pathname.includes(targetPath)) {
107106
return;
108107
}
109-
108+
110109
// Use replace instead of push to prevent stack accumulation on rapid clicks
111110
router.push(`/components/${componentPath}` as any);
112111
};
113112

114113
// Filter out bottomsheet components and components without paths
115-
const filteredComponents = components.map(category => ({
116-
...category,
117-
components: category.components.filter(component =>
118-
component.path &&
119-
!component.name.toLowerCase().includes('bottomsheet') &&
120-
!component.path.toLowerCase().includes('bottomsheet')
121-
)
122-
})).filter(category => category.components.length > 0);
114+
const filteredComponents = useMemo(
115+
() =>
116+
components
117+
.map((category) => ({
118+
...category,
119+
components: category.components.filter(
120+
(component) =>
121+
component.path &&
122+
!component.name.toLowerCase().includes('bottomsheet') &&
123+
!component.path.toLowerCase().includes('bottomsheet')
124+
),
125+
}))
126+
.filter((category) => category.components.length > 0),
127+
[]
128+
);
129+
130+
const renderCategoryItem = ({ item: category }: any) => (
131+
<Box className="mt-4 border-b border-outline-100 pb-8 px-5 md:px-20">
132+
<Heading size="lg" className="text-typography-900 mb-4">
133+
{category.category}
134+
</Heading>
135+
<Grid
136+
className="gap-5"
137+
_extra={{
138+
className: 'grid-cols-2 md:grid-cols-4 xl:grid-cols-6',
139+
}}
140+
>
141+
{category.components.map((component: any) => (
142+
<GridItem
143+
_extra={{
144+
className: 'col-span-1',
145+
}}
146+
key={component.name}
147+
>
148+
<ComponentCard
149+
component={component}
150+
onPress={() => handleComponentPress(component.path!)}
151+
/>
152+
</GridItem>
153+
))}
154+
</Grid>
155+
</Box>
156+
);
123157

124158
return (
125159
<SafeAreaView className="flex-1 bg-background-0">
126-
<ScrollView className="flex-1" showsVerticalScrollIndicator={false}>
127-
<Header />
128-
<VStack className="p-5 md:px-20">
129-
{filteredComponents.map((category) => (
130-
<Box
131-
key={category.category}
132-
className="mt-4 border-b border-outline-100 pb-8"
133-
>
134-
<Heading size="lg" className="text-typography-900 mb-4">
135-
{category.category}
136-
</Heading>
137-
<Grid
138-
className="gap-5"
139-
_extra={{
140-
className: 'grid-cols-2 md:grid-cols-4 xl:grid-cols-6',
141-
}}
142-
>
143-
{category.components.map((component) => (
144-
<GridItem
145-
_extra={{
146-
className: 'col-span-1',
147-
}}
148-
key={component.name}
149-
>
150-
<ComponentCard
151-
component={component}
152-
onPress={() => handleComponentPress(component.path!)}
153-
/>
154-
</GridItem>
155-
))}
156-
</Grid>
157-
</Box>
158-
))}
159-
</VStack>
160-
</ScrollView>
160+
<FlatList
161+
data={filteredComponents}
162+
renderItem={renderCategoryItem}
163+
ListHeaderComponent={<Header />}
164+
keyExtractor={(item) => item.category}
165+
contentContainerStyle={{ paddingVertical: 20 }}
166+
showsVerticalScrollIndicator={false}
167+
removeClippedSubviews={true}
168+
maxToRenderPerBatch={3}
169+
updateCellsBatchingPeriod={50}
170+
initialNumToRender={2}
171+
windowSize={5}
172+
/>
161173
</SafeAreaView>
162174
);
163175
}

0 commit comments

Comments
 (0)