Horizontal Card List with Multiple Meta Text
Screen is created using these React Native Core Components: <SafeAreaView />
, <View />
, <Text />
, <TouchableOpacity />
, <ScrollView />
import React from 'react';
import {
StyleSheet,
Dimensions,
SafeAreaView,
View,
Text,
TouchableOpacity,
ScrollView,
} from 'react-native';
import FeatherIcon from 'react-native-vector-icons/Feather''@expo/vector-icons/Feather';
const items = [
{
icon: 'figma',
label: 'Senior UI/UX Designer',
company: 'Figma',
jobType: 'Full Time',
years: '2019-2023',
},
{
icon: 'github',
label: 'Mid-level Designer',
company: 'GitHub',
jobType: 'Full Time',
years: '2017-2019',
},
{
icon: 'twitter',
label: 'Junior Designer',
company: 'Twitter',
jobType: 'Full Time',
years: '2015-2017',
},
];
const items_2 = [
{
icon: 'code',
label: 'TypeScript',
company: '8 endorsements',
jobType: '2 experiences',
years: 'GitHub & Figma',
},
{
icon: 'git-merge',
label: 'Git',
company: '3 endorsements',
jobType: '1 experience',
years: 'GitHub',
},
];
const CARD_WIDTH = Math.min(Dimensions.get('screen').width * 0.75, 400);
export default function Example() {
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#FBFCFF' }}>
<View style={styles.container}>
<Text style={styles.title}>Work Profile</Text>
<View style={styles.list}>
<View style={styles.listHeader}>
<Text style={styles.listTitle}>My Experience</Text>
<TouchableOpacity
onPress={() => {
// handle onPress
}}>
<Text style={styles.listAction}>View All</Text>
</TouchableOpacity>
</View>
<ScrollView
contentContainerStyle={styles.listContent}
horizontal={true}
showsHorizontalScrollIndicator={false}>
{items.map(({ icon, label, company, jobType, years }, index) => (
<TouchableOpacity
key={index}
onPress={() => {
// handle onPress
}}>
<View style={styles.card}>
<View style={styles.cardTop}>
<View style={styles.cardIcon}>
<FeatherIcon
color="#000"
name={icon}
size={24} />
</View>
<View style={styles.cardBody}>
<Text style={styles.cardTitle}>{label}</Text>
<Text style={styles.cardSubtitle}>{company}</Text>
</View>
</View>
<View style={styles.cardFooter}>
<Text style={styles.cardFooterText}>{jobType}</Text>
<Text style={styles.cardFooterText}>{years}</Text>
</View>
</View>
</TouchableOpacity>
))}
</ScrollView>
</View>
<View style={styles.list}>
<View style={styles.listHeader}>
<Text style={styles.listTitle}>Skills</Text>
<TouchableOpacity
onPress={() => {
// handle onPress
}}>
<Text style={styles.listAction}>View All</Text>
</TouchableOpacity>
</View>
<ScrollView
contentContainerStyle={styles.listContent}
horizontal={true}
showsHorizontalScrollIndicator={false}>
{items_2.map(({ icon, label, company, jobType, years }, index) => (
<TouchableOpacity
key={index}
onPress={() => {
// handle onPress
}}>
<View style={styles.card}>
<View style={styles.cardTop}>
<View style={styles.cardIcon}>
<FeatherIcon
color="#000"
name={icon}
size={24} />
</View>
<View style={styles.cardBody}>
<Text style={styles.cardTitle}>{label}</Text>
<Text style={styles.cardSubtitle}>{company}</Text>
</View>
</View>
<View style={styles.cardFooter}>
<Text style={styles.cardFooterText}>{jobType}</Text>
<Text style={styles.cardFooterText}>{years}</Text>
</View>
</View>
</TouchableOpacity>
))}
</ScrollView>
</View>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
paddingVertical: 24,
paddingHorizontal: 0,
flexGrow: 1,
flexShrink: 1,
flexBasis: 0,
},
title: {
paddingHorizontal: 24,
fontSize: 32,
fontWeight: '700',
color: '#1d1d1d',
marginBottom: 12,
},
/** List */
list: {
marginBottom: 24,
},
listHeader: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 24,
},
listTitle: {
fontSize: 18,
fontWeight: '600',
lineHeight: 22,
color: '#121a26',
},
listAction: {
fontSize: 14,
fontWeight: '500',
lineHeight: 20,
color: '#778599',
},
listContent: {
paddingVertical: 12,
paddingHorizontal: 18,
},
/** Card */
card: {
width: CARD_WIDTH,
paddingVertical: 16,
paddingHorizontal: 20,
borderRadius: 12,
backgroundColor: '#fff',
marginHorizontal: 6,
shadowColor: '#90a0ca',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 1,
},
cardTop: {
flexDirection: 'row',
alignItems: 'center',
},
cardIcon: {
width: 44,
height: 44,
borderRadius: 9999,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#eff1f5',
},
cardBody: {
paddingLeft: 12,
},
cardTitle: {
fontSize: 15,
fontWeight: '600',
lineHeight: 18,
color: '#121a26',
marginBottom: 4,
},
cardSubtitle: {
fontSize: 14,
fontWeight: '500',
lineHeight: 18,
color: '#778599',
},
cardFooter: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
marginTop: 18,
},
cardFooterText: {
fontSize: 13,
fontWeight: '500',
lineHeight: 18,
color: '#778599',
},
});
Dependencies
Before getting started, make sure you have all the necessary dependencies for this component. Follow the steps below to install any missing dependencies.
-
Install the package.
npm install --save react-native-vector-icons
-
Link the native packages for iOS.
npx pod-install
In React Native 0.60+ the CLI autolink feature links the module while building the app.
-
Add Fonts to the
Info.plist
file.
Open your XCode project, right click on the Info.plist
, and select Open As -> Source Code
.
Next, copy the fonts below into your Info.plist
.
<key>UIAppFonts</key>
<array>
<string>AntDesign.ttf</string>
<string>Entypo.ttf</string>
<string>EvilIcons.ttf</string>
<string>Feather.ttf</string>
<string>FontAwesome.ttf</string>
<string>FontAwesome5_Brands.ttf</string>
<string>FontAwesome5_Regular.ttf</string>
<string>FontAwesome5_Solid.ttf</string>
<string>FontAwesome6_Brands.ttf</string>
<string>FontAwesome6_Regular.ttf</string>
<string>FontAwesome6_Solid.ttf</string>
<string>Foundation.ttf</string>
<string>Ionicons.ttf</string>
<string>MaterialIcons.ttf</string>
<string>MaterialCommunityIcons.ttf</string>
<string>SimpleLineIcons.ttf</string>
<string>Octicons.ttf</string>
<string>Zocial.ttf</string>
<string>Fontisto.ttf</string>
</array>
Note: You can only select the fonts you would like to use in your React Native Application.
After you added these fonts the Info.plist
file should look like this:
-
Add
fonts.gradle
for Android.
Open android/app/build.gradle
(NOT android/build.gradle
) and add the following code to the bottom:
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
If you want to customize fonts, use:
project.ext.vectoricons = [
iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf' ]
]
apply from: file("../../node_modules/react-native-vector-icons/fonts.gradle")
Original instructions can be found on Github: https://github.com/oblador/react-native-vector-icons