Skip to content

Commit dedef94

Browse files
committed
fix(Bubble Icon Event Handlers): Allow bubble icons to be interactive
#21
1 parent 5cb4691 commit dedef94

5 files changed

Lines changed: 1107 additions & 541 deletions

File tree

components/TimelineEvent.js

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import React, { Component } from 'react'
21
import PropTypes from 'prop-types'
2+
import React, { Component } from 'react'
3+
34
import s from './styles'
45

56
class TimelineEvent extends Component {
@@ -16,8 +17,13 @@ class TimelineEvent extends Component {
1617
}
1718

1819
mergeNotificationStyle(iconColor, bubbleStyle, orientation) {
19-
const iconColorStyle = iconColor ? { ...s.eventType, ...{ color: iconColor, borderColor: iconColor } } : s.eventType
20-
const leftOrRight = orientation === 'right' ? { ...s['eventType--right'] } : { ...s['eventType--left'] }
20+
const iconColorStyle = iconColor
21+
? { ...s.eventType, ...{ color: iconColor, borderColor: iconColor } }
22+
: s.eventType
23+
const leftOrRight =
24+
orientation === 'right'
25+
? { ...s['eventType--right'] }
26+
: { ...s['eventType--left'] }
2127
return { ...iconColorStyle, ...leftOrRight, ...bubbleStyle }
2228
}
2329

@@ -43,7 +49,8 @@ class TimelineEvent extends Component {
4349

4450
toggleStyle() {
4551
const { container, cardHeaderStyle, collapsible } = this.props
46-
const messageStyle = container === 'card' ? { ...s.cardTitle, ...cardHeaderStyle } : {}
52+
const messageStyle =
53+
container === 'card' ? { ...s.cardTitle, ...cardHeaderStyle } : {}
4754
return collapsible ? { ...s.toggleEnabled, ...messageStyle } : messageStyle
4855
}
4956

@@ -59,7 +66,10 @@ class TimelineEvent extends Component {
5966
<div style={s.messageAfter} />
6067
</div>
6168
) : (
62-
<span style={{ fontWeight: 500, fontSize: 16, cursor: 'pointer' }} onClick={this.toggleContent}>
69+
<span
70+
style={{ fontWeight: 500, fontSize: 16, cursor: 'pointer' }}
71+
onClick={this.toggleContent}
72+
>
6373
6474
</span>
6575
)
@@ -80,22 +90,47 @@ class TimelineEvent extends Component {
8090
orientation,
8191
collapsible,
8292
onClick,
93+
onIconClick,
8394
className
8495
} = this.props
85-
const leftOrRightEventStyling = orientation === 'right' ? { ...s['event--right'] } : { ...s['event--left'] }
86-
const leftOrRightButtonStyling = orientation === 'left' ? { ...s['actionButtons--right'] } : { ...s['actionButtons--left'] }
96+
const leftOrRightEventStyling =
97+
orientation === 'right'
98+
? { ...s['event--right'] }
99+
: { ...s['event--left'] }
100+
const leftOrRightButtonStyling =
101+
orientation === 'left'
102+
? { ...s['actionButtons--right'] }
103+
: { ...s['actionButtons--left'] }
87104
return (
88105
<div style={{ ...s.event, ...leftOrRightEventStyling }}>
89-
<div style={this.mergeNotificationStyle(iconColor, bubbleStyle, orientation)}>
90-
<span style={{ ...s.materialIcons, ...iconStyle }}>{icon}</span>
106+
<div
107+
style={this.mergeNotificationStyle(
108+
iconColor,
109+
bubbleStyle,
110+
orientation
111+
)}
112+
>
113+
<span
114+
style={{ ...s.materialIcons, ...iconStyle }}
115+
onClick={onIconClick}
116+
>
117+
{icon}
118+
</span>
91119
</div>
92120
<div style={this.containerStyle()} {...{ onClick, className }}>
93121
<div style={s.eventContainerBefore} />
94-
<div style={this.toggleStyle()} onClick={collapsible && this.toggleContent}>
122+
<div
123+
style={this.toggleStyle()}
124+
onClick={collapsible && this.toggleContent}
125+
>
95126
{createdAt && <div style={this.timeStyle()}>{createdAt}</div>}
96127
<div style={titleStyle}>{title}</div>
97-
{subtitle && <div style={{ ...s.subtitle, ...subtitleStyle }}>{subtitle}</div>}
98-
<div style={{ ...s.actionButtons, ...leftOrRightButtonStyling }}>{buttons}</div>
128+
{subtitle && (
129+
<div style={{ ...s.subtitle, ...subtitleStyle }}>{subtitle}</div>
130+
)}
131+
<div style={{ ...s.actionButtons, ...leftOrRightButtonStyling }}>
132+
{buttons}
133+
</div>
99134
</div>
100135
{this.props.children && this.renderChildren()}
101136
</div>
@@ -125,7 +160,8 @@ TimelineEvent.propTypes = {
125160
collapsible: PropTypes.bool,
126161
showContent: PropTypes.bool,
127162
className: PropTypes.string,
128-
onClick: PropTypes.func
163+
onClick: PropTypes.func,
164+
onIconClick: PropTypes.func
129165
}
130166

131167
TimelineEvent.defaultProps = {
@@ -140,7 +176,8 @@ TimelineEvent.defaultProps = {
140176
orientation: 'left',
141177
showContent: false,
142178
className: '',
143-
onClick: () => {}
179+
onClick: () => {},
180+
onIconClick: () => {}
144181
}
145182

146183
export default TimelineEvent

components/styles.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ let style = {
6767
height: 32,
6868
position: 'relative',
6969
justifyContent: 'center',
70+
cursor: 'pointer',
7071
alignSelf: 'center',
7172
alignItems: 'center'
7273
},

stories/App.story.js

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import React, { Component } from 'react'
21
import { storiesOf } from '@storybook/react'
3-
import { Timeline, TimelineEvent, TimelineBlip } from '../components/index'
2+
import React, { Component } from 'react'
3+
4+
import { Timeline, TimelineBlip, TimelineEvent } from '../components'
45
import Image from './sample.jpg'
56

67
const globalStyles = {
@@ -189,7 +190,7 @@ storiesOf('Timeline', module)
189190
{ info: 'Timeline event container can be modelled as a card' }
190191
)
191192
.add(
192-
'Event handlers',
193+
'Content Event handlers',
193194
() => (
194195
<Timeline>
195196
<TimelineEvent
@@ -205,6 +206,51 @@ storiesOf('Timeline', module)
205206
),
206207
{ info: 'Timeline events can listen to user actions' }
207208
)
209+
.add(
210+
'Icon Event handlers',
211+
() => {
212+
class IconEventDemo extends React.Component {
213+
constructor(props) {
214+
super(props)
215+
this.state = {
216+
active: true,
217+
iconColor: 'red'
218+
}
219+
this.toggleEvent = this.toggleEvent.bind(this)
220+
}
221+
222+
get icon() {
223+
return this.state.active ? 'stop' : 'play_arrow'
224+
}
225+
226+
toggleEvent() {
227+
alert('Will toggle event status between play and stop')
228+
this.setState({
229+
active: !this.state.active,
230+
iconColor: this.state.iconColor === 'red' ? 'green' : 'red'
231+
})
232+
}
233+
234+
render() {
235+
return (
236+
<Timeline>
237+
<TimelineEvent
238+
title="Playing Beethoven's Moonlight Sonata"
239+
createdAt='2016-09-12 10:06 PM'
240+
icon={<i className='material-icons md-18'>{this.icon}</i>}
241+
iconColor={this.state.iconColor}
242+
onIconClick={this.toggleEvent}
243+
>
244+
Press icon on the bubble to stop music
245+
</TimelineEvent>
246+
</Timeline>
247+
)
248+
}
249+
}
250+
return <IconEventDemo />
251+
},
252+
{ info: 'Timeline events can listen to user actions' }
253+
)
208254
.add(
209255
'Event Styling',
210256
() => (

0 commit comments

Comments
 (0)