Skip to content

Instantly share code, notes, and snippets.

@danielsmykowski1
Created November 23, 2019 23:52
Show Gist options
  • Save danielsmykowski1/7511697097d587e98a53f92964b3bf94 to your computer and use it in GitHub Desktop.
Save danielsmykowski1/7511697097d587e98a53f92964b3bf94 to your computer and use it in GitHub Desktop.
A React-Native custom list item component.
import React, { Component } from 'react';
import {
Text, TouchableOpacity, View, StyleSheet
} from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome5';
import LinearGradient from 'react-native-linear-gradient';
import {
Fonts, Colors, Styles, Metrics
} from '../../themes';
const colors = {
highlight: [Colors.primary2, Colors.primary6],
normal: [Colors.primary3, Colors.primary4]
};
const styles = {
container: {
marginHorizontal: 15,
marginVertical: 10,
borderRadius: 3,
shadowColor: '#00000080',
shadowOpacity: 1,
shadowOffset: {
width: 0,
height: 2
},
shadowRadius: 5,
elevation: 5
},
inner: {
borderRadius: 3,
paddingHorizontal: 14,
paddingVertical: 8
},
actionBar: {
flexDirection: 'row',
marginBottom: 10
},
no: {
color: Colors.white,
fontFamily: Fonts.family.primary.bold,
fontSize: Fonts.size.nm
},
smartPickButton: {
paddingRight: 17
},
deleteButton: {
paddingLeft: 17
},
buttonIcon: {
color: Colors.warning,
fontSize: 22
},
separator: {
width: 1,
height: 24,
backgroundColor: Colors.primary
},
content: {
},
numbers: {
flexDirection: 'row',
marginHorizontal: -8
},
number: {
marginHorizontal: 8,
backgroundColor: Colors.primary5,
alignItems: 'center',
justifyContent: 'center'
},
numberText: {
fontFamily: Fonts.family.primary.black,
fontSize: Fonts.size.lg,
color: Colors.white
}
};
class TicketListItem extends Component {
constructor(props) {
super(props);
this.state = {};
}
getNumbers(numbers, fill = false) {
const {
maxCount
} = this.props;
const ret = numbers.map(item => `${item}`);
if (fill) {
for (let i = ret.length; i < maxCount; i++) {
ret.push('');
}
}
return ret;
}
render() {
const {
editMode, data, style, innerStyle, onPress, onSmartPick, onDelete
} = this.props;
const numbers = this.getNumbers(data, editMode);
const numberWidth = ((Metrics.dimension.width - 60 - 16 * 5) / 6);
return (
<TouchableOpacity
onPress={onPress}
style={StyleSheet.flatten([styles.container, style])}
activeOpacity={0.8}
>
<LinearGradient
style={StyleSheet.flatten([styles.inner, innerStyle])}
colors={editMode ? colors.highlight : colors.normal}
>
<View style={styles.actionBar}>
<Text style={styles.no}>{this.props.no}</Text>
<View style={Styles.container} />
<TouchableOpacity
style={styles.smartPickButton}
onPress={onSmartPick}
activeOpacity={0.9}
>
<Icon name="dice" style={styles.buttonIcon} />
</TouchableOpacity>
<View style={styles.separator} />
<TouchableOpacity
style={styles.deleteButton}
onPress={onDelete}
activeOpacity={0.9}
>
<Icon name="trash-alt" style={styles.buttonIcon} />
</TouchableOpacity>
</View>
<View
style={StyleSheet.flatten([
styles.numbers,
{
height: numberWidth
}
])}
>
{
numbers.map((number, index) => (
<View
style={[
styles.number,
{
width: numberWidth,
height: numberWidth,
borderRadius: numberWidth
}
]}
key={`${index}`}
>
<Text style={styles.numberText}>{number}</Text>
</View>
))
}
</View>
</LinearGradient>
</TouchableOpacity>
);
}
}
TicketListItem.defaultProps = {
editMode: true,
style: {},
innerStyle: {},
data: [],
no: 1,
maxCount: 6,
onPress: () => { },
onDelete: () => { },
onSmarkPick: () => { }
};
export default TicketListItem;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment