-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathmore-info-button.jsx
More file actions
101 lines (86 loc) · 2.1 KB
/
Copy pathmore-info-button.jsx
File metadata and controls
101 lines (86 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import './more-info-button.scss'
import React from 'react'
import uuid from '../util/uuid'
const DEFAULT_LABEL = '?'
class MoreInfoButton extends React.Component {
static get defaultProps() {
return {
label: DEFAULT_LABEL
}
}
constructor() {
super()
this.boundOnMouseOver = this.onMouseOver.bind(this)
this.boundOnMouseOut = this.onMouseOut.bind(this)
this.boundOnClick = this.onClick.bind(this)
this.hide = this.hide.bind(this)
this.state = {
mode: 'hidden',
id: uuid() // Used to create a unique DOM ID for aria-labelledby
}
this.dialogRef = React.createRef()
}
hide() {
this.setState({ mode: 'hidden' })
}
onMouseOver() {
if (this.state.mode === 'hidden') {
this.setState({ mode: 'hover' })
}
}
onMouseOut() {
if (this.state.mode === 'hover') {
this.hide()
}
}
onClick() {
if (this.state.mode === 'clicked') {
this.hide()
} else {
this.setState({ mode: 'clicked' })
}
}
componentDidUpdate() {
if (this.state.mode === 'clicked') {
this.dialogRef.current.focus()
}
}
render() {
const isShowing = this.state.mode === 'hover' || this.state.mode === 'clicked'
return (
<div
className={`obojobo-draft--components--more-info-button ${
this.props.label === DEFAULT_LABEL ? 'is-default-label' : 'is-not-default-label'
} is-mode-${this.state.mode}`}
>
<button
type="button" // Prevents click event when inside a <form>
onMouseOver={this.boundOnMouseOver}
onMouseOut={this.boundOnMouseOut}
onClick={this.boundOnClick}
aria-label={this.props.ariaLabel || 'More info'}
>
{this.props.label}
</button>
{isShowing ? (
<div
className="info"
role="dialog"
tabIndex="-1"
onBlur={this.hide}
ref={this.dialogRef}
aria-labelledby={`obojobo-draft--components--more-info-button--container--${this.state.id}`}
>
<div
id={`obojobo-draft--components--more-info-button--container--${this.state.id}`}
className="container"
>
{this.props.children}
</div>
</div>
) : null}
</div>
)
}
}
export default MoreInfoButton