From a95522395c376c0d004eafc2ff537b54bee74eaf Mon Sep 17 00:00:00 2001 From: Fabio Cigliano Date: Tue, 5 Feb 2019 11:01:58 +1300 Subject: [PATCH 1/3] fix(lineWidth) center timeline when having different line width --- src/index.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/index.js b/src/index.js index c6f82c8..8906845 100644 --- a/src/index.js +++ b/src/index.js @@ -74,9 +74,22 @@ type State = { class Timeline extends React.Component { state = { x: 0, - width: 0 + width: 0, + maxLineWidth: DEFAULT_LINE_WIDTH, }; + static getDerivedStateFromProps (props, state) { + let maxLineWidth = props.lineWidth || DEFAULT_LINE_WIDTH + + (props.data || []).forEach(function (item) { + maxLineWidth = Math.max(maxLineWidth, item.lineWidth || maxLineWidth) + }) + + return { + ...state, + } + } + render() { const { style, data, flatListStyle, flatListProps, keyExtractor } = this.props; @@ -223,6 +236,7 @@ class Timeline extends React.Component { const lineColorToUse = item.lineColor || lineColor || DEFAULT_LINE_COLOR; const lineWidthToUse = item.lineWidth || lineWidth || DEFAULT_LINE_WIDTH; + const marginDelta = Math.floor((this.state.maxLineWidth - lineWidthToUse) / 2.0); const isLast = renderFullLine ? !renderFullLine : index + 1 === data.length; const borderColor = isLast ? 'transparent' : lineColorToUse; @@ -235,8 +249,8 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: lineWidthToUse, borderRightWidth: 0, - marginLeft: 20, - paddingLeft: 20 + marginLeft: 20 + marginDelta, + paddingLeft: 20 + marginDelta }; break; case 'single-column-right': @@ -244,8 +258,8 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: 0, borderRightWidth: lineWidthToUse, - marginRight: 20, - paddingRight: 20 + marginRight: 20 + marginDelta, + paddingRight: 20 + marginDelta }; break; case 'two-column': @@ -255,15 +269,15 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: lineWidthToUse, borderRightWidth: 0, - marginLeft: 20, - paddingLeft: 20 + marginLeft: 20 + marginDelta, + paddingLeft: 20 + marginDelta } : { borderColor: borderColor, borderLeftWidth: 0, borderRightWidth: lineWidthToUse, - marginRight: 20, - paddingRight: 20 + marginRight: 20 + marginDelta, + paddingRight: 20 + marginDelta }; break; } From ce7a0a9e315bcf1c7bb4722e0b86b27d8930851b Mon Sep 17 00:00:00 2001 From: Fabio Cigliano Date: Tue, 5 Feb 2019 11:35:52 +1300 Subject: [PATCH 2/3] fix(circle) move circle up to center it between the two segments --- src/index.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index 8906845..33dc74a 100644 --- a/src/index.js +++ b/src/index.js @@ -333,7 +333,7 @@ class Timeline extends React.Component { const circleSizeToUse = item.circleSize || circleSize || DEFAULT_CIRCLE_SIZE; const circleColorToUse = item.circleColor || circleColor || DEFAULT_CIRCLE_COLOR; - const lineWidthToUse = item.lineWidth || lineWidth || DEFAULT_LINE_WIDTH; + const lineWidthToUse = this.state.maxLineWidth; const { x, width } = this.state; @@ -345,7 +345,8 @@ class Timeline extends React.Component { height: x ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: x - circleSizeToUse / 2 + (lineWidthToUse - 1) / 2 + left: x - circleSizeToUse / 2 + (lineWidthToUse - 1) / 2, + top: - circleSizeToUse / 2 }; break; case 'single-column-right': @@ -354,7 +355,8 @@ class Timeline extends React.Component { height: width ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2 + left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2, + top: - circleSizeToUse / 2 }; break; case 'two-column': @@ -363,7 +365,8 @@ class Timeline extends React.Component { height: width ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2 + left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2, + top: - circleSizeToUse / 2 }; break; } From 430975ee3123414547b3ea4f2503178c35fb4cbe Mon Sep 17 00:00:00 2001 From: Fabio Cigliano Date: Wed, 8 May 2019 11:05:38 +1200 Subject: [PATCH 3/3] chore(center) added centerLineAndCircle to allow backward compatibility --- src/index.js | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/index.js b/src/index.js index 33dc74a..6ce6649 100644 --- a/src/index.js +++ b/src/index.js @@ -46,7 +46,8 @@ export type Props = { dotColor?: string, circleStyle?: ViewStyleProp, separator?: boolean, - separatorStyle?: ViewStyleProp + separatorStyle?: ViewStyleProp, + centerLineAndCircle?: boolean }; export type Item = { @@ -87,6 +88,7 @@ class Timeline extends React.Component { return { ...state, + maxLineWidth, } } @@ -100,7 +102,7 @@ class Timeline extends React.Component { data={data} keyExtractor={keyExtractor} renderItem={this.renderItem} - style={[styles.listview, this.props.flatListStyle]} + style={[styles.listview, flatListStyle]} {...flatListProps} /> @@ -221,7 +223,7 @@ class Timeline extends React.Component { }; renderEvent = ({ item, index }: FlatListItemType) => { - const { renderEvent } = this.props; + const { renderEvent, centerLineAndCircle } = this.props; if (renderEvent) { return renderEvent({ item, index }); } @@ -236,7 +238,9 @@ class Timeline extends React.Component { const lineColorToUse = item.lineColor || lineColor || DEFAULT_LINE_COLOR; const lineWidthToUse = item.lineWidth || lineWidth || DEFAULT_LINE_WIDTH; - const marginDelta = Math.floor((this.state.maxLineWidth - lineWidthToUse) / 2.0); + const margin = centerLineAndCircle + ? Math.floor((this.state.maxLineWidth - lineWidthToUse) / 2.0) + : 0; const isLast = renderFullLine ? !renderFullLine : index + 1 === data.length; const borderColor = isLast ? 'transparent' : lineColorToUse; @@ -249,8 +253,8 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: lineWidthToUse, borderRightWidth: 0, - marginLeft: 20 + marginDelta, - paddingLeft: 20 + marginDelta + marginLeft: 20 + margin, + paddingLeft: 20 + margin }; break; case 'single-column-right': @@ -258,8 +262,8 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: 0, borderRightWidth: lineWidthToUse, - marginRight: 20 + marginDelta, - paddingRight: 20 + marginDelta + marginRight: 20 + margin, + paddingRight: 20 + margin }; break; case 'two-column': @@ -269,26 +273,26 @@ class Timeline extends React.Component { borderColor: borderColor, borderLeftWidth: lineWidthToUse, borderRightWidth: 0, - marginLeft: 20 + marginDelta, - paddingLeft: 20 + marginDelta + marginLeft: 20 + margin, + paddingLeft: 20 + margin } : { borderColor: borderColor, borderLeftWidth: 0, borderRightWidth: lineWidthToUse, - marginRight: 20 + marginDelta, - paddingRight: 20 + marginDelta + marginRight: 20 + margin, + paddingRight: 20 + margin }; break; } - const { onEventPress, detailContainerStyle } = this.props; + const { onEventPress, detailContainerStyle, centerLineAndCircle } = this.props; return ( { + const { x, width } = evt.nativeEvent.layout; if (!this.state.x && !this.state.width) { - const { x, width } = evt.nativeEvent.layout; this.setState({ x, width }); } }} @@ -324,7 +328,8 @@ class Timeline extends React.Component { }; renderCircle({ item, index }: FlatListItemType) { - const { renderCircle } = this.props; + const { renderCircle, centerLineAndCircle } = this.props; + if (renderCircle) { return renderCircle({ item, index }); } @@ -333,7 +338,9 @@ class Timeline extends React.Component { const circleSizeToUse = item.circleSize || circleSize || DEFAULT_CIRCLE_SIZE; const circleColorToUse = item.circleColor || circleColor || DEFAULT_CIRCLE_COLOR; - const lineWidthToUse = this.state.maxLineWidth; + const lineWidthToUse = centerLineAndCircle + ? this.state.maxLineWidth + : item.lineWidth || lineWidth || DEFAULT_LINE_WIDTH; const { x, width } = this.state; @@ -345,8 +352,7 @@ class Timeline extends React.Component { height: x ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: x - circleSizeToUse / 2 + (lineWidthToUse - 1) / 2, - top: - circleSizeToUse / 2 + left: x - circleSizeToUse / 2 + (lineWidthToUse - 1) / 2 }; break; case 'single-column-right': @@ -355,8 +361,7 @@ class Timeline extends React.Component { height: width ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2, - top: - circleSizeToUse / 2 + left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2 }; break; case 'two-column': @@ -365,12 +370,15 @@ class Timeline extends React.Component { height: width ? circleSizeToUse : 0, borderRadius: circleSizeToUse / 2, backgroundColor: circleColorToUse, - left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2, - top: - circleSizeToUse / 2 + left: width - circleSizeToUse / 2 - (lineWidthToUse - 1) / 2 }; break; } + if (centerLineAndCircle) { + localCircleStyle.top = - circleSizeToUse; + } + const { innerCircleType = DEFAULT_INNER_CIRCLE_TYPE, iconStyle,