From claude-code-toolkit
Provides React Native and Flutter patterns for performant lists with FlatList, stack/tab navigation, and widget structure for mobile apps.
npx claudepluginhub rohitg00/awesome-claude-code-toolkitThis skill uses the workspace's default tool permissions.
```tsx
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Guides MCP server integration in Claude Code plugins via .mcp.json or plugin.json configs for stdio, SSE, HTTP types, enabling external services as tools.
import { View, Text, FlatList, StyleSheet, Platform } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
interface Product {
id: string;
name: string;
price: number;
image: string;
}
function ProductList({ products }: { products: Product[] }) {
return (
<SafeAreaView style={styles.container}>
<FlatList
data={products}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <ProductCard product={item} />}
contentContainerStyle={styles.list}
ItemSeparatorComponent={() => <View style={styles.separator} />}
ListEmptyComponent={<EmptyState message="No products found" />}
initialNumToRender={10}
maxToRenderPerBatch={10}
windowSize={5}
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
},
list: {
padding: 16,
},
separator: {
height: 12,
},
});
Use FlatList for scrollable lists (never ScrollView with .map()). Set windowSize and maxToRenderPerBatch for large lists.
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
type RootStackParams = {
Tabs: undefined;
ProductDetail: { productId: string };
Cart: undefined;
};
const Stack = createNativeStackNavigator<RootStackParams>();
const Tab = createBottomTabNavigator();
function TabNavigator() {
return (
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
</Tab.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Tabs" component={TabNavigator} options={{ headerShown: false }} />
<Stack.Screen name="ProductDetail" component={ProductDetailScreen} />
<Stack.Screen name="Cart" component={CartScreen} options={{ presentation: "modal" }} />
</Stack.Navigator>
</NavigationContainer>
);
}
class ProductCard extends StatelessWidget {
final Product product;
final VoidCallback onTap;
const ProductCard({
super.key,
required this.product,
required this.onTap,
});
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Card(
elevation: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ClipRRect(
borderRadius: const BorderRadius.vertical(top: Radius.circular(8)),
child: Image.network(
product.imageUrl,
height: 200,
width: double.infinity,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => const Icon(Icons.broken_image, size: 64),
),
),
Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(product.name, style: Theme.of(context).textTheme.titleMedium),
const SizedBox(height: 4),
Text("\$${product.price.toStringAsFixed(2)}",
style: Theme.of(context).textTheme.bodyLarge),
],
),
),
],
),
),
);
}
}
import { useWindowDimensions } from "react-native";
function useResponsive() {
const { width } = useWindowDimensions();
return {
isPhone: width < 768,
isTablet: width >= 768 && width < 1024,
isDesktop: width >= 1024,
columns: width < 768 ? 1 : width < 1024 ? 2 : 3,
};
}
function ProductGrid({ products }: { products: Product[] }) {
const { columns } = useResponsive();
return (
<FlatList
data={products}
numColumns={columns}
key={columns}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ flex: 1, maxWidth: `${100 / columns}%`, padding: 8 }}>
<ProductCard product={item} />
</View>
)}
/>
);
}
import { Platform } from "react-native";
const styles = StyleSheet.create({
shadow: Platform.select({
ios: {
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: {
elevation: 4,
},
default: {},
}),
});
ScrollView with .map() for dynamic lists (use FlatList or SectionList)StyleSheet.create)InteractionManager)FlatList used for all scrollable lists with keyExtractorSafeAreaViewStyleSheet.create (not inline objects)Platform.select