Skip to content

Commit 75138a3

Browse files
committed
Border Colour, Refactoring, Tests, Makefile
1 parent 6ee266e commit 75138a3

File tree

13 files changed

+17447
-203
lines changed

13 files changed

+17447
-203
lines changed

Makefile

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ STANDALONE = standalone
55
SRC = src
66
DIST = dist
77
TEST = test/*.spec.js
8-
MOCHA_OPTS = --compilers js:babel-core/register --require test/setup.js -b --timeout 20000 --reporter spec
98

109
lint:
1110
@echo Linting...
@@ -51,11 +50,11 @@ deployJS:
5150

5251
unitTest:
5352
@echo Unit testing..
54-
@$(NODE_BIN)/mocha --require @babel/register 'test/*.spec.js'
53+
@$(NODE_BIN)/mocha --require @babel/register $(TEST)
5554

5655
deploy: lint
5756
@echo Deploy...
58-
@make unitTest
57+
@make unitTest
5958
@rm -rf dist && mkdir dist
6059
@rm -rf $(EXAMPLE_DIST) && mkdir -p $(EXAMPLE_DIST)
6160
@make deployJS
@@ -64,5 +63,5 @@ deploy: lint
6463
@make genStand
6564
@echo success!
6665

67-
.PHONY: lint convertCSS genStand devJS devCSS devServer dev deployExample deployJS deployCSS deploy
66+
.PHONY: lint convertCSS genStand devJS devCSS devServer dev unitTest deployExample deployJS deployCSS deploy
6867

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ className | data-class | String | | extra custom class, can use !importan
7070
delayUpdate | data-delay-update | Number | | `<p data-tip="tooltip" data-delay-update='1000'></p>` or `<ReactTooltip delayUpdate={1000} />` Sets a delay in calling getContent if the tooltip is already shown and you mouse over another target
7171
insecure | null | Bool | true, false | Whether to inject the style header into the page dynamically (violates CSP style-src but is a convenient default)
7272
border | data-border | Bool | true, false | Add one pixel white border
73-
textColor | data-text-color | String | e.g. red | Popup text color - required with the `backgroundColor` value
74-
backgroundColor | data-background-color | String | e.g. yellow | Popup background color - required with the `textColor` value
73+
textColor | data-text-color | String | e.g. red | Popup text color
74+
backgroundColor | data-background-color | String | e.g. yellow | Popup background color
75+
borderColor | data-border-color | String | e.g. green | Popup border color - enabled by the `border` value
7576
arrowColor | data-arrow-color | String | e.g. #fff | Popup arrow color - if not specified, will use the `backgroundColor` value
7677
getContent | null | Func or Array | (dataTip) => {}, [(dataTip) => {}, Interval] | Generate the tip content dynamically
7778
afterShow | null | Func | (evt) => {} | Function that will be called after tooltip show, with event that triggered show

package-lock.json

Lines changed: 15 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"version": "0.0.0-semantic-release",
44
"description": "react tooltip component",
55
"main": "dist/index.js",
6-
"module": "dist/index.es.js",
7-
"jsnext:main": "dist/index.es.js",
6+
"module": "dist/index.js",
7+
"jsnext:main": "dist/index.ex.js",
88
"engines": {
99
"node": ">=8",
1010
"npm": ">=5"
@@ -66,6 +66,7 @@
6666
"dependencies": {
6767
"aphrodite-jss": "^2.1.0",
6868
"classnames": "^2.2.6",
69+
"lodash": "^4.17.15",
6970
"prop-types": "^15.7.2"
7071
},
7172
"devDependencies": {

src/decorators/defaultStyles.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
import _ from 'lodash'
2+
13
/**
24
* Default pop-up style values (text color, background color).
35
*/
46
const defaultColors = {
5-
'dark': {'textColor': '#fff', 'backgroundColor': '#222', 'arrowColor': '#222'},
6-
'success': {'textColor': '#fff', 'backgroundColor': '#8DC572', 'arrowColor': '#8DC572'},
7-
'warning': {'textColor': '#fff', 'backgroundColor': '#F0AD4E', 'arrowColor': '#F0AD4E'},
8-
'error': {'textColor': '#fff', 'backgroundColor': '#BE6464', 'arrowColor': '#BE6464'},
9-
'info': {'textColor': '#fff', 'backgroundColor': '#337AB7', 'arrowColor': '#337AB7'},
10-
'light': {'textColor': '#222', 'backgroundColor': '#fff', 'arrowColor': '#fff'}
7+
'dark': {'text': '#fff', 'background': '#222', 'border': 'transparent', 'arrow': '#222'},
8+
'success': {'text': '#fff', 'background': '#8DC572', 'border': 'transparent', 'arrow': '#8DC572'},
9+
'warning': {'text': '#fff', 'background': '#F0AD4E', 'border': 'transparent', 'arrow': '#F0AD4E'},
10+
'error': {'text': '#fff', 'background': '#BE6464', 'border': 'transparent', 'arrow': '#BE6464'},
11+
'info': {'text': '#fff', 'background': '#337AB7', 'border': 'transparent', 'arrow': '#337AB7'},
12+
'light': {'text': '#222', 'background': '#fff', 'border': 'transparent', 'arrow': '#fff'}
1113
}
1214

13-
export function getDefaultPopupColors (type) { // TODO: gotta have a switch there looking at the classes originally provided by the plugin
14-
return defaultColors[type]
15+
export function getDefaultPopupColors (type) {
16+
return _.cloneDeep(defaultColors[type])
1517
}

src/decorators/styler.js

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
import { StyleSheet } from 'aphrodite-jss'
2+
import { getDefaultPopupColors } from './defaultStyles'
3+
24
/**
35
* Generates the tooltip style based on the element-specified "data-type" property.
46
*/
57
export function getTooltipStyle (colors) {
6-
const textColor = colors.textColor
7-
const backgroundColor = colors.backgroundColor
8-
const arrowColor = colors.arrowColor
8+
const textColor = colors.text
9+
const backgroundColor = colors.background
10+
const borderColor = colors.border
11+
const arrowColor = colors.arrow
912

1013
return StyleSheet.create({
1114
'__react_component_tooltip': {
1215
'color': textColor,
1316
'backgroundColor': backgroundColor,
17+
'border': '1px solid ' + borderColor,
1418

1519
'&.place-top': {
1620
'margin-top': '-10px'
1721
},
22+
'&.place-top:before': {
23+
'border-top': '8px solid ' + borderColor
24+
},
1825
'&.place-top:after': {
1926
'border-left': '8px solid transparent',
2027
'border-right': '8px solid transparent',
@@ -29,6 +36,9 @@ export function getTooltipStyle (colors) {
2936
'&.place-bottom': {
3037
'margin-top': '10px'
3138
},
39+
'&.place-bottom:before': {
40+
'border-bottom': '8px solid ' + borderColor
41+
},
3242
'&.place-bottom:after': {
3343
'border-left': '8px solid transparent',
3444
'border-right': '8px solid transparent',
@@ -43,6 +53,9 @@ export function getTooltipStyle (colors) {
4353
'&.place-left': {
4454
'margin-left': '-10px'
4555
},
56+
'&.place-left:before': {
57+
'border-left': '8px solid ' + borderColor
58+
},
4659
'&.place-left:after': {
4760
'border-top': '5px solid transparent',
4861
'border-bottom': '5px solid transparent',
@@ -57,6 +70,9 @@ export function getTooltipStyle (colors) {
5770
'&.place-right': {
5871
'margin-left': '10px'
5972
},
73+
'&.place-right:before': {
74+
'border-right': '8px solid ' + borderColor
75+
},
6076
'&.place-right:after': {
6177
'border-top': '5px solid transparent',
6278
'border-bottom': '5px solid transparent',
@@ -70,3 +86,39 @@ export function getTooltipStyle (colors) {
7086
}
7187
})
7288
}
89+
90+
/**
91+
* Get popup colors
92+
*/
93+
export function getPopupColors (customColors, type, hasBorder) {
94+
let colors
95+
96+
const textColor = customColors.text
97+
const backgroundColor = customColors.background
98+
const borderColor = customColors.border
99+
const arrowColor = customColors.arrow ? customColors.arrow : customColors.background
100+
101+
colors = getDefaultPopupColors(type)
102+
103+
if (textColor) {
104+
colors.text = textColor
105+
}
106+
107+
if (backgroundColor) {
108+
colors.background = backgroundColor
109+
}
110+
111+
if (hasBorder) {
112+
if (borderColor) {
113+
colors.border = borderColor
114+
} else {
115+
colors.border = 'white'
116+
}
117+
}
118+
119+
if (arrowColor) {
120+
colors.arrow = arrowColor
121+
}
122+
123+
return colors
124+
}

src/index.js

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
/* eslint no-unused-vars: 0 */ // --> OFF
2-
/* eslint no-undef: 0 */ // --> OFF
3-
41
'use strict'
52

63
import React from 'react'
@@ -24,8 +21,7 @@ import nodeListToArray from './utils/nodeListToArray'
2421
/* CSS */
2522
import cssStyle from './style'
2623
import { css } from 'aphrodite-jss'
27-
import { getTooltipStyle } from './decorators/styler'
28-
import { getDefaultPopupColors } from './decorators/defaultStyles'
24+
import { getTooltipStyle, getPopupColors } from './decorators/styler'
2925

3026
@staticMethods
3127
@windowListener
@@ -45,6 +41,7 @@ class ReactTooltip extends React.Component {
4541
border: PropTypes.bool,
4642
textColor: PropTypes.string,
4743
backgroundColor: PropTypes.string,
44+
borderColor: PropTypes.string,
4845
arrowColor: PropTypes.string,
4946
insecure: PropTypes.bool,
5047
class: PropTypes.string,
@@ -83,13 +80,15 @@ class ReactTooltip extends React.Component {
8380

8481
constructor (props) {
8582
super(props)
83+
8684
this.state = {
8785
place: props.place || 'top', // Direction of tooltip
8886
desiredPlace: props.place || 'top',
8987
type: 'dark', // Color theme of tooltip
9088
effect: 'float', // float or fixed
9189
show: false,
9290
border: false,
91+
customColors: {},
9392
offset: {},
9493
extraClass: '',
9594
html: false,
@@ -196,12 +195,14 @@ class ReactTooltip extends React.Component {
196195
*/
197196
getTargetArray (id) {
198197
let targetArray
198+
199199
if (!id) {
200200
targetArray = document.querySelectorAll('[data-tip]:not([data-for])')
201201
} else {
202202
const escaped = id.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
203203
targetArray = document.querySelectorAll(`[data-tip][data-for="${escaped}"]`)
204204
}
205+
205206
// targetArray is a NodeList, convert it to a real array
206207
return nodeListToArray(targetArray)
207208
}
@@ -345,6 +346,12 @@ class ReactTooltip extends React.Component {
345346
desiredPlace: desiredPlace,
346347
place: place,
347348
type: target.getAttribute('data-type') || self.props.type || 'dark',
349+
customColors: {
350+
text: target.getAttribute('data-text-color') || self.props.textColor || null,
351+
background: target.getAttribute('data-background-color') || self.props.backgroundColor || null,
352+
border: target.getAttribute('data-border-color') || self.props.borderColor || null,
353+
arrow: target.getAttribute('data-arrow-color') || self.props.arrowColor || null
354+
},
348355
effect: effect,
349356
offset: offset,
350357
html: target.getAttribute('data-html') ? target.getAttribute('data-html') === 'true' : self.props.html || false,
@@ -356,7 +363,9 @@ class ReactTooltip extends React.Component {
356363
disable: target.getAttribute('data-tip-disable') ? target.getAttribute('data-tip-disable') === 'true' : self.props.disable || false,
357364
currentTarget: target
358365
}, () => {
359-
if (scrollHide) self.addScrollListener(self.state.currentTarget)
366+
if (scrollHide) {
367+
self.addScrollListener(self.state.currentTarget)
368+
}
360369
self.updateTooltip(e)
361370

362371
if (getContent && Array.isArray(getContent)) {
@@ -408,7 +417,9 @@ class ReactTooltip extends React.Component {
408417
show: true
409418
}, () => {
410419
this.updatePosition()
411-
if (isInvisible && afterShow) afterShow(e)
420+
if (isInvisible && afterShow) {
421+
afterShow(e)
422+
}
412423
})
413424
}
414425
}
@@ -471,7 +482,9 @@ class ReactTooltip extends React.Component {
471482
show: false
472483
}, () => {
473484
this.removeScrollListener()
474-
if (isVisible && afterHide) afterHide(e)
485+
if (isVisible && afterHide) {
486+
afterHide(e)
487+
}
475488
})
476489
}
477490

@@ -518,30 +531,12 @@ class ReactTooltip extends React.Component {
518531
this.updatePosition()
519532
})
520533
}
534+
521535
// Set tooltip position
522536
node.style.left = result.position.left + 'px'
523537
node.style.top = result.position.top + 'px'
524538
}
525539

526-
/**
527-
* Determine popup colors
528-
*/
529-
setPopupColors () {
530-
let colors
531-
532-
let textColor = this.props.textColor
533-
let backgroundColor = this.props.backgroundColor
534-
let arrowColor = this.props.arrowColor ? this.props.arrowColor : this.props.backgroundColor
535-
536-
if (textColor && backgroundColor) {
537-
colors = {'textColor': textColor, 'backgroundColor': backgroundColor, 'arrowColor': arrowColor}
538-
} else {
539-
colors = getDefaultPopupColors(this.state.type)
540-
}
541-
542-
return colors
543-
}
544-
545540
/**
546541
* Set style tag in header
547542
* in this way we can insert default css
@@ -571,6 +566,11 @@ class ReactTooltip extends React.Component {
571566
clearInterval(this.intervalUpdateContent)
572567
}
573568

569+
hasCustomColors () {
570+
return Boolean((Object.keys(this.state.customColors).find(color => color !== 'border' && this.state.customColors[color]) ||
571+
(this.state.border && this.state.customColors['border'])))
572+
}
573+
574574
render () {
575575
const {extraClass, html, ariaProps, disable} = this.state
576576
const placeholder = this.getTooltipContent()
@@ -584,13 +584,12 @@ class ReactTooltip extends React.Component {
584584
{'place-bottom': this.state.place === 'bottom'},
585585
{'place-left': this.state.place === 'left'},
586586
{'place-right': this.state.place === 'right'},
587-
{['type-' + (this.props.textColor && this.props.backgroundColor ? 'custom' : this.state.type)]: this.state.type},
587+
{['type-' + (this.hasCustomColors() ? 'custom' : this.state.type)]: this.state.type},
588588
{'allow_hover': this.props.delayUpdate},
589589
{'allow_click': this.props.clickable}
590590
)
591591

592-
const colors = this.setPopupColors()
593-
const tooltipStyle = getTooltipStyle(colors)
592+
const tooltipStyle = getTooltipStyle(getPopupColors(this.state.customColors, this.state.type, this.state.border))
594593

595594
let Wrapper = this.props.wrapper
596595
if (ReactTooltip.supportedWrappers.indexOf(Wrapper) < 0) {

0 commit comments

Comments
 (0)