Skip to content

Commit

Permalink
Support ReactTooltip.show() #47
Browse files Browse the repository at this point in the history
  • Loading branch information
wwayne committed Aug 4, 2016
1 parent 0d5a791 commit da4e965
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
21 changes: 16 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,32 @@ Check the example [React-tooltip Test](http://wwayne.com/react-tooltip)
3. When using react component as tooltip, you can have many `<ReactTooltip />` in a page but they should have different **id**

## Static Methods
`ReactTooltip.hide()`: Hide the tooltip manually
**ReactTooltip.hide()**: Hide the tooltip manually

`ReactTooltip.rebuild()`: Rebinding tooltip to the corresponding elements
**ReactTooltip.rebuild()**: Rebinding tooltip to the corresponding elements

I suggest always put `<ReactTooltip />` in the Highest level or smart component of Redux, so you might need these static
method to control tooltip's behaviour in some situations
**ReactTooltip.show(target)**: Show specific tooltip manually, for example:

```
import {findDOMNode} from 'react-dom'
import ReactTooltip from 'react-tooltip'
<p ref='foo' data-tip='tooltip'></p>
<button onClick={() => { ReactTooltip.show(findDOMNode(this.refs.foo)) }}></button>
<ReactTooltip />
```

## Trouble Shooting
#### Using tooltip within the modal (e.g. [react-modal](https://github.com/reactjs/react-modal))
### Using tooltip within the modal (e.g. [react-modal](https://github.com/reactjs/react-modal))
The component was designed to set a `<Reactooltip />` one place then use tooltip everywhere, but a lot of people stuck in using this component with modal, you can check the discussion [here](https://github.com/wwayne/react-tooltip/issues/130), the summarization of solving the problem is as following:

1. Put `<ReactTooltip />` out of the `<Modal>`
2. Use `React.rebuild()` when opening the modal
3. If your modal's z-index happens to higher than the tooltip, use the attribute `class` to custom your tooltip's z-index

>I suggest always put `<ReactTooltip />` in the Highest level or smart component of Redux, so you might need these static
method to control tooltip's behaviour in some situations

## Article
[How I insert sass into react component](https://medium.com/@wwayne_me/how-i-insert-sass-into-my-npm-react-component-b46b9811c226#.gi4hxu44a)

Expand Down
25 changes: 21 additions & 4 deletions src/decorators/staticMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
*/
import CONSTANT from '../constant'

const dispatchGlobalEvent = (eventName) => {
const dispatchGlobalEvent = (eventName, opts) => {
// Compatibale with IE
// @see http://stackoverflow.com/questions/26596123/internet-explorer-9-10-11-event-constructor-doesnt-work
let event

if (typeof window.Event === 'function') {
event = new window.Event(eventName)
if (typeof window.CustomEvent === 'function') {
event = new window.CustomEvent(eventName, { detail: opts })
} else {
event = document.createEvent('Event')
event.initEvent(eventName, false, true)
event.initEvent(eventName, false, true, opts)
}

window.dispatchEvent(event)
Expand All @@ -35,10 +35,27 @@ export default function (target) {
dispatchGlobalEvent(CONSTANT.GLOBAL.REBUILD)
}

/**
* Show specific tooltip
* @trigger ReactTooltip.show()
*/
target.show = (target) => {
dispatchGlobalEvent(CONSTANT.GLOBAL.SHOW, {target})
}

target.prototype.globalRebuild = function () {
if (this.mount) {
this.unbindListener()
this.bindListener()
}
}

target.prototype.globalShow = function (event) {
if (this.mount) {
// Create a fake event, specific show will limit the type to `solid`
// only `float` type cares e.clientX e.clientY
const e = { currentTarget: event.detail.target }
this.showTooltip(e, true)
}
}
}
5 changes: 5 additions & 0 deletions src/decorators/windowListener.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export default function (target) {
window.removeEventListener(CONSTANT.GLOBAL.REBUILD, this.globalRebuild)
window.addEventListener(CONSTANT.GLOBAL.REBUILD, this.globalRebuild, false)

// ReactTooltip.show
window.removeEventListener(CONSTANT.GLOBAL.SHOW, this.globalShow)
window.addEventListener(CONSTANT.GLOBAL.SHOW, this.globalShow, false)

// Resize
window.removeEventListener('resize', this.onWindowResize)
window.addEventListener('resize', this.onWindowResize, false)
Expand All @@ -21,6 +25,7 @@ export default function (target) {
target.prototype.unbindWindowEvents = function () {
window.removeEventListener(CONSTANT.GLOBAL.HIDE, this.hideTooltip)
window.removeEventListener(CONSTANT.GLOBAL.REBUILD, this.globalRebuild)
window.removeEventListener(CONSTANT.GLOBAL.SHOW, this.globalShow)
window.removeEventListener('resize', this.onWindowResize)
}

Expand Down
15 changes: 11 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class ReactTooltip extends Component {
'updateTooltip',
'hideTooltip',
'globalRebuild',
'globalShow',
'onWindowResize'
])

Expand Down Expand Up @@ -198,7 +199,13 @@ class ReactTooltip extends Component {
/**
* When mouse enter, show the tooltip
*/
showTooltip (e) {
showTooltip (e, isGlobalCall) {
if (isGlobalCall) {
// Don't trigger other elements belongs to other ReactTooltip
const targetArray = this.getTargetArray(this.props.id)
const isMyElement = targetArray.some(ele => ele === e.currentTarget)
if (!isMyElement || this.state.show) return
}
// Get the tooltip content
// calculate in this phrase so that tip width height can be detected
const {children, multiline, getContent} = this.props
Expand All @@ -216,13 +223,13 @@ class ReactTooltip extends Component {
}
const placeholder = getTipContent(originTooltip, content, isMultiline)

// If it is focus event, switch to `solid` effect
const isFocus = e instanceof window.FocusEvent
// If it is focus event or called by ReactTooltip.show, switch to `solid` effect
const switchToSolid = e instanceof window.FocusEvent || isGlobalCall
this.setState({
placeholder,
place: e.currentTarget.getAttribute('data-place') || this.props.place || 'top',
type: e.currentTarget.getAttribute('data-type') || this.props.type || 'dark',
effect: isFocus && 'solid' || e.currentTarget.getAttribute('data-effect') || this.props.effect || 'float',
effect: switchToSolid && 'solid' || e.currentTarget.getAttribute('data-effect') || this.props.effect || 'float',
offset: e.currentTarget.getAttribute('data-offset') || this.props.offset || {},
html: e.currentTarget.getAttribute('data-html')
? e.currentTarget.getAttribute('data-html') === 'true'
Expand Down

0 comments on commit da4e965

Please sign in to comment.