Timeline component for React Native App work for Android and iOS
It's a fork of react-native-timeline-listview with some updates including FlatList, because old ListView is deprecated.
Examples in examples folder and on Expo https://expo.io/@eugnis/react-native-timeline-flatlist-examples
Table of Contents
- Installation
- Usage
- Column Format (in v.0.2.0)
- Configuration
- Shift problem
npm i react-native-timeline-flatlist --save or
yarn add react-native-timeline-flatlist import Timeline from 'react-native-timeline-flatlist' constructor(){ super() this.data = [ {time: '09:00', title: 'Event 1', description: 'Event 1 Description'}, {time: '10:45', title: 'Event 2', description: 'Event 2 Description'}, {time: '12:00', title: 'Event 3', description: 'Event 3 Description'}, {time: '14:00', title: 'Event 4', description: 'Event 4 Description'}, {time: '16:30', title: 'Event 5', description: 'Event 5 Description'} ] } render(){ return( <Timeline data={this.data} /> ) }render(){ return( <Timeline //..other props circleSize={20} circleColor='rgb(45,156,219)' lineColor='rgb(45,156,219)' timeContainerStyle={{minWidth:52, marginTop: -5}} timeStyle={{textAlign: 'center', backgroundColor:'#ff9797', color:'white', padding:5, borderRadius:13}} descriptionStyle={{color:'gray'}} options={{ style:{paddingTop:5} }} isUsingFlatlist={true} /> ) }render(){ return( <Timeline //..other props innerCircle={'dot'} /> ) }constructor(){ super() this.data = [ {time: '09:00', title: 'Archery Training', description: 'The Beginner Archery and Beginner Crossbow course does not require you to bring any equipment, since everything you need will be provided for the course. ',lineColor:'#009688', icon: require('../img/archery.png')}, {time: '10:45', title: 'Play Badminton', description: 'Badminton is a racquet sport played using racquets to hit a shuttlecock across a net.', icon: require('../img/badminton.png')}, {time: '12:00', title: 'Lunch', icon: require('../img/lunch.png')}, {time: '14:00', title: 'Watch Soccer', description: 'Team sport played between two teams of eleven players with a spherical ball. ',lineColor:'#009688', icon: require('../img/soccer.png')}, {time: '16:30', title: 'Go to Fitness center', description: 'Look out for the Best Gym & Fitness Centers around me :)', icon: require('../img/dumbbell.png')} ] } render(){ return( <Timeline //..other props innerCircle={'icon'} /> ) }Also you can pass any React element as icon or iconDefault:
this.data = [ ... {time: '12:00', title: 'Custom rendered icon', icon: <Image style={{width: 20, height: 20}} source={{uri: 'https://reactnative.dev/img/tiny_logo.png'}} />}, ... ] } constructor(){ super() this.renderDetail = this.renderDetail.bind(this) this.data = [ { time: '09:00', title: 'Archery Training', description: 'The Beginner Archery and Beginner Crossbow course does not require you to bring any equipment, since everything you need will be provided for the course. ', lineColor:'#009688', icon: require('../img/archery.png'), imageUrl: 'https://cloud.githubusercontent.com/assets/21040043/24240340/c0f96b3a-0fe3-11e7-8964-fe66e4d9be7a.jpg' }, { time: '10:45', title: 'Play Badminton', description: 'Badminton is a racquet sport played using racquets to hit a shuttlecock across a net.', icon: require('../img/badminton.png'), imageUrl: 'https://cloud.githubusercontent.com/assets/21040043/24240405/0ba41234-0fe4-11e7-919b-c3f88ced349c.jpg' }, { time: '12:00', title: 'Lunch', icon: require('../img/lunch.png'), }, { time: '14:00', title: 'Watch Soccer', description: 'Team sport played between two teams of eleven players with a spherical ball. ', lineColor:'#009688', icon: require('../img/soccer.png'), imageUrl: 'https://cloud.githubusercontent.com/assets/21040043/24240419/1f553dee-0fe4-11e7-8638-6025682232b1.jpg' }, { time: '16:30', title: 'Go to Fitness center', description: 'Look out for the Best Gym & Fitness Centers around me :)', icon: require('../img/dumbbell.png'), imageUrl: 'https://cloud.githubusercontent.com/assets/21040043/24240422/20d84f6c-0fe4-11e7-8f1d-9dbc594d0cfa.jpg' } ] } renderDetail(rowData, sectionID, rowID) { let title = <Text style={[styles.title]}>{rowData.title}</Text> var desc = null if(rowData.description && rowData.imageUrl) desc = ( <View style={styles.descriptionContainer}> <Image source={{uri: rowData.imageUrl}} style={styles.image}/> <Text style={[styles.textDescription]}>{rowData.description}</Text> </View> ) return ( <View style={{flex:1}}> {title} {desc} </View> ) } render(){ return( <Timeline //..other props renderDetail={this.renderDetail} /> ) }see full override render example
onRefresh(){ //set initial data } onEndReached() { //fetch next data } renderFooter() { //show loading indicator if (this.state.waiting) { return <ActivityIndicator />; } else { return <Text>~</Text>; } } render(){ return( <Timeline //..other props options={{ refreshControl: ( <RefreshControl refreshing={this.state.isRefreshing} onRefresh={this.onRefresh} /> ), renderFooter: this.renderFooter, onEndReached: this.onEndReached }} /> ) }see full refresh and load more example
render(){ return( <Timeline //..other props columnFormat='single-column-right' /> ) }see full single column right example
render(){ return( <Timeline //..other props columnFormat='two-column' /> ) }render(){ return( <Timeline //..other props showTime={false} /> ) }| Property | Type | Default | Description |
|---|---|---|---|
| time | string | null | event time |
| title | string | null | event title |
| description | string or object | null | event description |
| lineWidth | int | same as lineWidth of 'Timeline' | event line width |
| lineColor | string | same as lineColor of 'Timeline' | event line color |
| columnSidePadding | int | 20 | custom event line side padding |
| columnSideMargin | int | 20 | custom event line side margin |
| eventContainerStyle | object | null | custom styles of line |
| circleSize | int | same as circleSize of 'Timeline' | event circle size |
| circleColor | string | same as circleColor of 'Timeline' | event circle color |
| dotColor | string | same as dotColor of 'Timeline' | event dot color (innerCircle = 'dot') |
| icon | obj(image source) or React.Element | same as icon of 'Timeline' | event icon (innerCircle = 'icon' or 'element') |
| position | string | null | event side in 'two-column' layout : 'left', 'right' |
| Property | Type | Default | Description |
|---|---|---|---|
| data | data object | null | timeline data |
| innerCircle | string | null | timeline mode : 'none', 'dot', 'icon', 'element' |
| separator | bool | true | render separator line of events |
| columnFormat | string | 'single-left' | can be 'single-column-left', 'single-column-right', 'two-column' |
| lineWidth | int | 2 | timeline line width |
| lineColor | string | '#007AFF' | timeline line color |
| circleSize | int | 16 | timeline circle size |
| circleColor | string | '#007AFF' | timeline circle color |
| dotColor | string | 'white' | timeline dot color (innerCircle = 'dot') |
| dotSize | int | circleSize / 2 | timeline dot size (innerCircle = 'dot') |
| iconDefault (or icon) | obj(image source) or React.Element | same as icon of 'Timeline' | default event icon |
| columnSidePadding | int | 20 | custom line side padding |
| columnSideMargin | int | 20 | custom line side margin |
| style | object | null | custom styles of Timeline container |
| listViewStyle | object | null | custom styles of inner ListView |
| listViewContainerStyle | object | null | custom styles of inner ListView container |
| timeStyle | object | null | custom styles of event time |
| titleStyle | object | null | custom styles of event title |
| descriptionStyle | object | null | custom styles of event description |
| iconStyle | object | null | custom styles of event icon |
| separatorStyle | object | null | custom styles of separator |
| rowContainerStyle | object | null | custom styles of event container |
| eventContainerStyle | object | null | custom styles of the event part of the row (line) |
| eventDetailStyle | object | null | custom styles of the event detail part of the row (line) |
| timeContainerStyle | object | null | custom styles of container of event time |
| detailContainerStyle | object | null | custom styles of container of event title and event description |
| onEventPress | function(event) | null | function to be invoked when event was pressed |
| renderTime | function(rowData, sectionID, rowID) | null | custom render event time |
| renderDetail | function(rowData, sectionID, rowID) | null | custom render event title and event description |
| renderCircle | function(rowData, sectionID, rowID) | null | custom render circle |
| renderFullLine | bool | false | render event border on last timeline item |
| options | object | null | ListView properties |
| showTime | boolean | true | Time container options |
| isUsingFlatlist | boolean | false | Render inner components in Flatlist (if false - render in View) |
Text width of event time may not be the same.
fix by add 'minWidth' in 'timeContainerStyle' to appropriate value
render(){ return( <Timeline //..other props timeContainerStyle={{minWidth:72}} /> ) }fix by add removeClippedSubviews: false into options
render(){ return( <Timeline //..other props options={{ removeClippedSubviews: false }} /> ) }









