Skip to content

Commit a5477b2

Browse files
committed
Add globalEventOff attribute
w
1 parent f3824f5 commit a5477b2

File tree

6 files changed

+49
-42
lines changed

6 files changed

+49
-42
lines changed

example/src/index.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ const Test = React.createClass({
152152

153153
<div className="example-jsx">
154154
<div className="side">
155-
<a data-for='customer-event' data-tip='customer show' data-event='click'>( •̀д•́)</a>
156-
<ReactTooltip id='customer-event' />
155+
<a data-for='customer-event' data-tip='customer show' data-event='click focus'>( •̀д•́)</a>
156+
<ReactTooltip id='customer-event' globalEventOff='click'/>
157157
</div>
158158

159159
<div className="side">
@@ -164,8 +164,8 @@ const Test = React.createClass({
164164
<br />
165165
<pre className='example-pre'>
166166
<div>
167-
<p>{"<a data-tip='customer show' data-event='click'>( •̀д•́)</a>\n" +
168-
"<ReactTooltip />"}</p>
167+
<p>{"<a data-tip='customer show' data-event='click focus'>( •̀д•́)</a>\n" +
168+
"<ReactTooltip globalEventOff='click' />"}</p>
169169
</div>
170170
<div>
171171
<p>{"<a data-tip='custom show and hide' data-event='click' data-event-off='dblclick'>( •̀д•́)</a>\n" +

src/decorators/customEvent.js

+11-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
const checkStatus = function (dataEventOff, e) {
1010
const {show} = this.state
1111
const dataIsCapture = e.currentTarget.getAttribute('data-iscapture')
12-
const isCapture = dataIsCapture && dataIsCapture === 'true' || this.state.isCapture
12+
const isCapture = dataIsCapture && dataIsCapture === 'true' || this.props.isCapture
1313
const currentItem = e.currentTarget.getAttribute('currentItem')
1414

1515
if (!isCapture) e.stopPropagation()
@@ -41,14 +41,18 @@ export default function (target) {
4141
/* Bind listener for custom event */
4242
target.prototype.customBindListener = function (ele) {
4343
const {event, eventOff} = this.state
44-
const dataEvent = event || ele.getAttribute('data-event')
45-
const dataEventOff = eventOff || ele.getAttribute('data-event-off')
44+
const dataEvent = ele.getAttribute('data-event') || event
45+
const dataEventOff = ele.getAttribute('data-event-off') || eventOff
4646

47-
ele.removeEventListener(dataEvent, checkStatus)
48-
ele.addEventListener(dataEvent, checkStatus.bind(this, dataEventOff), false)
47+
dataEvent.split(' ').forEach(event => {
48+
ele.removeEventListener(event, checkStatus)
49+
ele.addEventListener(event, checkStatus.bind(this, dataEventOff), false)
50+
})
4951
if (dataEventOff) {
50-
ele.removeEventListener(dataEventOff, this.hideTooltip)
51-
ele.addEventListener(dataEventOff, ::this.hideTooltip, false)
52+
dataEventOff.split(' ').forEach(event => {
53+
ele.removeEventListener(event, this.hideTooltip)
54+
ele.addEventListener(event, ::this.hideTooltip, false)
55+
})
5256
}
5357
}
5458

src/decorators/isCapture.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Util method to judge if it should follow capture model
3+
*/
4+
5+
export default function (target) {
6+
target.prototype.isCapture = function (currentTarget) {
7+
const dataIsCapture = currentTarget.getAttribute('data-iscapture')
8+
return dataIsCapture && dataIsCapture === 'true' || this.props.isCapture || false
9+
}
10+
}

src/decorators/staticMethods.js

-13
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,4 @@ export default function (target) {
4141
this.bindListener()
4242
}
4343
}
44-
45-
/**
46-
* show a specific tooltip
47-
* @trigger ReactTooltip.show()
48-
*/
49-
target.show = (id) => {
50-
dispatchGlobalEvent(CONSTANT.GLOBAL.SHOW)
51-
}
52-
53-
target.prototype.globalShow = function () {
54-
// id comes from I don't know
55-
this.getTargetArray(id)
56-
}
5744
}

src/decorators/windowListener.js

-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@ export default function (target) {
1313
window.removeEventListener(CONSTANT.GLOBAL.REBUILD, this.globalRebuild)
1414
window.addEventListener(CONSTANT.GLOBAL.REBUILD, ::this.globalRebuild, false)
1515

16-
// ReactTooltip.show
17-
window.removeEventListener(CONSTANT.GLOBAL.SHOW, this.globalShow)
18-
window.addEventListener(CONSTANT.GLOBAL.SHOW, ::this.globalShow, false)
19-
2016
// Resize
2117
window.removeEventListener('resize', this.onWindowResize)
2218
window.addEventListener('resize', ::this.onWindowResize, false)

src/index.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import classname from 'classnames'
88
import staticMethods from './decorators/staticMethods'
99
import windowListener from './decorators/windowListener'
1010
import customEvent from './decorators/customEvent'
11+
import isCapture from './decorators/isCapture'
1112

1213
/* Utils */
1314
import getPosition from './utils/getPosition'
@@ -16,8 +17,7 @@ import getTipContent from './utils/getTipContent'
1617
/* CSS */
1718
import cssStyle from './style'
1819

19-
/* TODO: attribute to enable global click to hide the tooltip */
20-
@staticMethods @windowListener @customEvent
20+
@staticMethods @windowListener @customEvent @isCapture
2121
class ReactTooltip extends Component {
2222

2323
static propTypes = {
@@ -33,10 +33,11 @@ class ReactTooltip extends Component {
3333
html: PropTypes.bool,
3434
delayHide: PropTypes.number,
3535
delayShow: PropTypes.number,
36-
event: PropTypes.any,
37-
eventOff: PropTypes.any,
36+
event: PropTypes.string,
37+
eventOff: PropTypes.string,
3838
watchWindow: PropTypes.bool,
39-
isCapture: PropTypes.bool
39+
isCapture: PropTypes.bool,
40+
globalEventOff: PropTypes.string
4041
}
4142

4243
constructor (props) {
@@ -55,7 +56,6 @@ class ReactTooltip extends Component {
5556
delayShow: 0,
5657
event: props.event || null,
5758
eventOff: props.eventOff || null,
58-
isCapture: props.isCapture || false,
5959
currentEvent: null, // Current mouse event
6060
currentTarget: null // Current target of mouse event
6161
}
@@ -106,10 +106,11 @@ class ReactTooltip extends Component {
106106
* These listeners used to trigger showing or hiding the tooltip
107107
*/
108108
bindListener () {
109-
const {id} = this.props
109+
const {id, globalEventOff} = this.props
110110
let targetArray = this.getTargetArray(id)
111111

112112
targetArray.forEach(target => {
113+
const isCaptureMode = this.isCapture(target)
113114
if (target.getAttribute('currentItem') === null) {
114115
target.setAttribute('currentItem', 'false')
115116
}
@@ -120,22 +121,28 @@ class ReactTooltip extends Component {
120121
}
121122

122123
target.removeEventListener('mouseenter', this.showTooltip)
123-
target.addEventListener('mouseenter', ::this.showTooltip, false)
124+
target.addEventListener('mouseenter', ::this.showTooltip, isCaptureMode)
124125
if (this.state.effect === 'float') {
125126
target.removeEventListener('mousemove', this.updateTooltip)
126-
target.addEventListener('mousemove', ::this.updateTooltip, false)
127+
target.addEventListener('mousemove', ::this.updateTooltip, isCaptureMode)
127128
}
128129

129130
target.removeEventListener('mouseleave', this.hideTooltip)
130-
target.addEventListener('mouseleave', ::this.hideTooltip, false)
131+
target.addEventListener('mouseleave', ::this.hideTooltip, isCaptureMode)
131132
})
133+
134+
// Global event to hide tooltip
135+
if (globalEventOff) {
136+
window.removeEventListener(globalEventOff, this.hideTooltip)
137+
window.addEventListener(globalEventOff, ::this.hideTooltip, false)
138+
}
132139
}
133140

134141
/**
135142
* Unbind listeners on target elements
136143
*/
137144
unbindListener () {
138-
const {id} = this.props
145+
const {id, globalEventOff} = this.props
139146
const targetArray = this.getTargetArray(id)
140147

141148
targetArray.forEach(target => {
@@ -148,6 +155,8 @@ class ReactTooltip extends Component {
148155
target.removeEventListener('mousemove', this.updateTooltip)
149156
target.removeEventListener('mouseleave', this.hideTooltip)
150157
})
158+
159+
if (globalEventOff) window.removeEventListener(globalEventOff, this.hideTooltip)
151160
}
152161

153162
/**
@@ -173,7 +182,7 @@ class ReactTooltip extends Component {
173182
border: e.currentTarget.getAttribute('data-border') === 'true' || this.props.border || false,
174183
extraClass: e.currentTarget.getAttribute('data-class') || this.props.class || ''
175184
}, () => {
176-
this.addScrollListener()
185+
this.addScrollListener(e)
177186
this.updateTooltip(e)
178187
})
179188
}
@@ -224,8 +233,9 @@ class ReactTooltip extends Component {
224233
* Add scroll eventlistener when tooltip show
225234
* automatically hide the tooltip when scrolling
226235
*/
227-
addScrollListener () {
228-
window.addEventListener('scroll', ::this.hideTooltip)
236+
addScrollListener (e) {
237+
const isCaptureMode = this.isCapture(e.currentTarget)
238+
window.addEventListener('scroll', ::this.hideTooltip, isCaptureMode)
229239
}
230240

231241
removeScrollListener () {

0 commit comments

Comments
 (0)