Skip to content

Commit 21c22d0

Browse files
committed
Merge branch 'tooltip'
2 parents 36c0d5a + cc0149e commit 21c22d0

File tree

2 files changed

+101
-61
lines changed

2 files changed

+101
-61
lines changed

components/SLDSTooltip/index.jsx

Lines changed: 70 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,77 +7,77 @@ Neither the name of salesforce.com, inc. nor the names of its contributors may b
77
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88
*/
99

10-
'use strict';
1110

12-
import React, {PropTypes} from 'react';
11+
import React from 'react';
1312
import SLDSPopover from '../SLDSPopover';
14-
15-
import cx from 'classnames';
16-
17-
module.exports = React.createClass( {
18-
19-
displayName: 'SLDSToolip',
20-
21-
propTypes: {
22-
align: PropTypes.string,
23-
children: PropTypes.node,
24-
content: PropTypes.node,
25-
hoverCloseDelay: PropTypes.number,
26-
openByDefault: PropTypes.bool,
27-
openOn: PropTypes.string,
28-
},
29-
30-
31-
getDefaultProps () {
32-
return {
33-
align: 'top',
34-
content: <span>Tooltip</span>,
35-
hoverCloseDelay: 350,
36-
openByDefault: false,
37-
openOn: 'hover',
38-
};
39-
},
40-
41-
getInitialState(){
42-
return {
13+
const classNames = require("classnames");
14+
15+
const displayName = "SLDSTooltip";
16+
const propTypes = {
17+
align: React.PropTypes.string,
18+
children: React.PropTypes.node,
19+
content: React.PropTypes.node,
20+
hoverCloseDelay: React.PropTypes.number,
21+
openByDefault: React.PropTypes.bool,
22+
openOn: React.PropTypes.string,
23+
};
24+
const defaultProps = {
25+
align: 'top',
26+
content: <span>Tooltip</span>,
27+
hoverCloseDelay: 350,
28+
openByDefault: false,
29+
openOn: 'hover',
30+
};
31+
32+
class SLDSTooltip extends React.Component {
33+
34+
constructor(props) {
35+
super(props);
36+
this.state = {
37+
isClosing: false,
4338
isOpen: this.props.openByDefault,
44-
isClosing: false
4539
};
46-
},
40+
}
41+
42+
componentDidMount() {
43+
this.setState({ isMounted: true });
44+
}
4745

48-
componentDidMount(){
49-
},
46+
componentWillUnmount() {
47+
this.setState({ isMounted: false });
48+
}
5049

51-
handleMouseClick(event) {
50+
handleMouseClick() {
5251
this.setState({
5352
isOpen: !this.state.isOpen,
5453
isClosing: !this.state.isOpen
5554
});
56-
},
55+
}
5756

5857

59-
handleMouseEnter(event) {
58+
handleMouseEnter() {
6059
this.setState({
6160
isOpen: true,
6261
isClosing: false
6362
});
64-
},
63+
}
64+
65+
handleMouseLeave() {
66+
this.setState({ isClosing: true });
6567

66-
handleMouseLeave(event) {
67-
this.setState({isClosing: true});
6868
setTimeout(()=>{
69-
if(this.isMounted && this.state.isClosing){
69+
if(this.state.isMounted && this.state.isClosing){
7070
this.setState({
7171
isOpen: false,
7272
isClosing: false
7373
});
7474
}
7575
},this.props.hoverCloseDelay)
76-
},
76+
}
7777

7878
getTooltipContent() {
7979
return <div className='slds-popover__body'>{this.props.content}</div>;
80-
},
80+
}
8181

8282
getHorizontalAlign() {
8383
if (this.props.align==='left') {
@@ -87,7 +87,7 @@ module.exports = React.createClass( {
8787
return 'right';
8888
}
8989
return 'center';
90-
},
90+
}
9191

9292
getVerticalAlign() {
9393
if (this.props.align==='bottom') {
@@ -97,25 +97,26 @@ module.exports = React.createClass( {
9797
return 'top';
9898
}
9999
return 'middle';
100-
},
100+
}
101101

102102
handleCancel() {
103103
this.setState({
104104
isOpen: false,
105105
isClosing: false
106106
});
107-
},
107+
}
108108

109-
getTooltip() {
110-
const style = {
111-
'slds-popover': true,
112-
'slds-popover--tooltip': true,
113-
'slds-nubbin--top': this.props.align === 'bottom',
114-
'slds-nubbin--bottom': this.props.align === 'top',
115-
'slds-nubbin--left': this.props.align === 'right',
116-
'slds-nubbin--right': this.props.align === 'left'
117-
};
109+
getClassName() {
110+
return classNames(this.props.className, "slds-popover", {
111+
["slds-popover--tooltip"]: true,
112+
["slds-nubbin--top"]: this.props.align === 'bottom',
113+
['slds-nubbin--bottom']: this.props.align === 'top',
114+
['slds-nubbin--left']: this.props.align === 'right',
115+
['slds-nubbin--right']: this.props.align === 'left'
116+
});
117+
}
118118

119+
getTooltip() {
119120
return this.state.isOpen?<SLDSPopover
120121
key={this.getHorizontalAlign()+' '+this.getVerticalAlign()}
121122
targetElement={this.refs.tooltipTarget}
@@ -128,20 +129,28 @@ module.exports = React.createClass( {
128129
horizontalAlign={this.getHorizontalAlign()}
129130
verticalAlign={this.getVerticalAlign()}
130131
flippable={false}
131-
onClose={this.handleCancel}>
132-
<div className={cx(style)}>
132+
onClose={this.handleCancel.bind(this)}>
133+
<div className={this.getClassName()} role="tooltip">
133134
{this.getTooltipContent()}
134135
</div>
135136
</SLDSPopover>:null;
136-
},
137+
}
137138

138139
render(){
139140
return (
140-
<span refs='tooltipTarget' onClick={this.props.openOn === 'click' ? this.handleMouseClick:null} onMouseEnter={this.props.openOn === 'hover' ? this.handleMouseEnter:null} onMouseLeave={this.props.openOn === 'hover' ? this.handleMouseLeave:null}>
141+
<span refs='tooltipTarget' onClick={this.props.openOn === 'click' ? this.handleMouseClick.bind(this):null} onMouseEnter={this.props.openOn === 'hover' ? this.handleMouseEnter.bind(this):null} onMouseLeave={this.props.openOn === 'hover' ? this.handleMouseLeave.bind(this):null}>
141142
{ this.props.children }
142143
{ this.getTooltip() }
143144
</span>
144145
);
145146
}
146147

147-
});
148+
}
149+
150+
151+
SLDSTooltip.displayName = displayName;
152+
SLDSTooltip.propTypes = propTypes;
153+
SLDSTooltip.defaultProps = defaultProps;
154+
155+
module.exports = SLDSTooltip;
156+

tests/SLDSTooltip/tooltip.test.jsx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,37 @@ describe('SLDSTooltip: ', function(){
1717
});
1818

1919
describe('component basic props render', function() {
20+
it('renders tooltip trigger text', function() {
21+
let triggerText = 'Click here for tooltip';
22+
let tooltip = generateTooltip(<SLDSTooltip align='left' content='This is more info. blah blah.' openOn='click'>{triggerText}</SLDSTooltip>);
23+
let tooltipTrigger = tooltip.innerText;
24+
expect(tooltipTrigger).to.equal(triggerText);
25+
});
26+
27+
it('aligns', function() {
28+
let popoverText = 'This is more info. blah blah.';
29+
let tooltip = generateTooltip(<SLDSTooltip align='right' content={popoverText} openOn='click'>Click Me</SLDSTooltip>);
30+
TestUtils.Simulate.click(tooltip);
31+
let reactId = tooltip.getElementsByTagName('noscript')[0].getAttribute("data-reactid");
32+
expect(reactId).to.equal('.v.$right middle');
33+
});
34+
});
35+
36+
describe('functionality works', function() {
37+
it("renders popover onHover with onOpen prop === 'hover'", function() {
38+
let popoverText = 'I open on hover.';
39+
let tooltip = generateTooltip(<SLDSTooltip align='right' content={popoverText} openOn='hover'>Hover Me</SLDSTooltip>);
40+
TestUtils.Simulate.mouseEnter(tooltip);
41+
TestUtils.Simulate.mouseLeave(tooltip);
42+
});
43+
44+
it("renders popover onClick with onOpen prop === 'click'", function() {
45+
let popoverText = 'I am aligned right.';
46+
let tooltip = generateTooltip(<SLDSTooltip align='right' content={popoverText} openOn='click'>Click Me</SLDSTooltip>);
47+
TestUtils.Simulate.click(tooltip);
48+
});
49+
2050
});
2151

52+
2253
});

0 commit comments

Comments
 (0)