Skip to content

Commit e579891

Browse files
author
Vic G
authored
Merge pull request #1520 from maxceem/issue-1508
issue #1508 - Dismissing a notification from the dropdown closes the menu
2 parents b4cc44a + dd63928 commit e579891

File tree

5 files changed

+273
-1
lines changed

5 files changed

+273
-1
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
require('./Dropdown.scss')
2+
3+
import React, { Component, PropTypes } from 'react'
4+
import classNames from 'classnames'
5+
6+
class Dropdown extends Component {
7+
constructor(props) {
8+
super(props)
9+
10+
this.state = { isHidden: true }
11+
12+
this.onClickOutside = this.onClickOutside.bind(this)
13+
this.onClick = this.onClick.bind(this)
14+
this.onClickOtherDropdown = this.onClickOtherDropdown.bind(this)
15+
}
16+
17+
onClickOutside(evt) {
18+
let currNode = evt.target
19+
let isDropdown = false
20+
21+
do {
22+
if(currNode.className
23+
&& currNode.className.indexOf
24+
&& currNode.className.indexOf('dropdown-wrap') > -1) {
25+
isDropdown = true
26+
break
27+
}
28+
29+
currNode = currNode.parentNode
30+
31+
if(!currNode)
32+
break
33+
} while(currNode.tagName)
34+
35+
if(!isDropdown) {
36+
this.setState({ isHidden: true })
37+
}
38+
}
39+
40+
onClick(evt) {
41+
const dropdownClicked = document.createEvent('Event')
42+
dropdownClicked.initEvent('dropdownClicked', true, false)
43+
44+
document.dispatchEvent(dropdownClicked)
45+
46+
this.setState({ isHidden: !this.state.isHidden })
47+
evt.stopPropagation()
48+
}
49+
50+
onClickOtherDropdown() {
51+
this.setState({ isHidden: true })
52+
}
53+
54+
componentDidMount() {
55+
document.removeEventListener('click', this.onClickOutside)
56+
document.removeEventListener('dropdownClicked', this.onClickOtherDropdown)
57+
58+
document.addEventListener('click', this.onClickOutside)
59+
document.addEventListener('dropdownClicked', this.onClickOtherDropdown)
60+
}
61+
62+
componentWillUnmount() {
63+
document.removeEventListener('click', this.onClickOutside)
64+
document.removeEventListener('dropdownClicked', this.onClickOtherDropdown)
65+
}
66+
67+
render() {
68+
const { className, pointerShadow, noPointer, pointerLeft, noAutoclose } = this.props
69+
const ddClasses = classNames('dropdown-wrap', {
70+
[`${className}`] : true,
71+
[`${ this.props.theme }`] : true,
72+
hide : this.state.isHidden
73+
})
74+
const ndClasses = classNames('Dropdown', {
75+
'pointer-shadow' : pointerShadow,
76+
'pointer-hide' : noPointer,
77+
'pointer-left' : pointerLeft,
78+
'no-autoclose' : noAutoclose
79+
})
80+
81+
return (
82+
<div className={ ddClasses } onClick={ noAutoclose ? () => {} : this.onClick } ref="Dropdown">
83+
{
84+
this.props.children.map((child, index) => {
85+
if (child.props.className.indexOf('dropdown-menu-header') > -1)
86+
return noAutoclose ? React.cloneElement(child, {
87+
onClick: this.onClick,
88+
key: child.props.key || index
89+
}) : child
90+
})
91+
}
92+
93+
<div className = {ndClasses}>
94+
{
95+
this.props.children.map((child) => {
96+
if (child.props.className.indexOf('dropdown-menu-list') > -1)
97+
return child
98+
})
99+
}
100+
</div>
101+
</div>
102+
)
103+
}
104+
}
105+
106+
Dropdown.propTypes = {
107+
children: PropTypes.array.isRequired
108+
}
109+
110+
export default Dropdown
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
@import 'tc-includes';
2+
3+
4+
.dropdown-wrap {
5+
cursor: pointer;
6+
position: relative;
7+
}
8+
9+
.Dropdown {
10+
background-color: #fff;
11+
box-shadow: 0 2px 7px rgba(0, 0, 0, 0.17);
12+
border-radius: 5px;
13+
display: inline-block;
14+
position: absolute;
15+
left: 0;
16+
top: 5px;
17+
width: 100%;
18+
z-index: 2;
19+
20+
ul {
21+
height: 100%;
22+
width: 100%;
23+
position: relative;
24+
z-index: 10;
25+
background-color: #fff;
26+
padding: 11px 20px;
27+
border-radius: 5px;
28+
29+
li {
30+
list-style: none;
31+
}
32+
33+
li a {
34+
color: #394146;
35+
font-family: "Roboto", Arial, Helvetica, sans-serif;
36+
font-size: 12px;
37+
display: block;
38+
line-height: 26px;
39+
}
40+
}
41+
}
42+
43+
.Dropdown.no-autoclose {
44+
cursor: default;
45+
}
46+
47+
.dropdown-wrap.default {
48+
border: 1px solid $tc-gray-20;
49+
display: flex;
50+
align-items: center;
51+
padding: calc(2 * #{$base_unit});
52+
position: relative;
53+
54+
.Dropdown {
55+
ul.dropdown-menu-list {
56+
padding: 10px 0px;
57+
li {
58+
padding: 0 20px;
59+
@include ellipsis;
60+
}
61+
62+
li:hover {
63+
background-color: $tc-gray-neutral-dark;
64+
}
65+
}
66+
}
67+
}
68+
69+
.dropdown-wrap.default::after {
70+
content: " ";
71+
width: 10px;
72+
height: 10px;
73+
display: block;
74+
right: 10px;
75+
top: 50%;
76+
position: absolute;
77+
transform: translateY(-50%) rotate(45deg);
78+
border-bottom: 2px solid $tc-gray-20;
79+
border-right: 2px solid $tc-gray-20;
80+
}
81+
82+
.dropdown-wrap.hide .Dropdown {
83+
display: none;
84+
}
85+
86+
.Dropdown.pointer-left:before {
87+
right: initial;
88+
left: 15px;
89+
}
90+
91+
.UserDropdownMenu .Dropdown.pointer-shadow {
92+
margin-top: 35px;
93+
94+
&:before {
95+
content: '';
96+
display: block;
97+
position: absolute;
98+
top: -6px;
99+
right: 24px;
100+
width: 12px;
101+
height: 12px;
102+
background: #FFFFFF;
103+
border-right: 1px solid $tc-gray-20;;
104+
border-bottom: 1px solid $tc-gray-20;;
105+
transform: rotate(-135deg);
106+
z-index:999;
107+
}
108+
}
109+
110+
.Dropdown.pointer-hide:before {
111+
display: none;
112+
}
113+
114+
.new-theme {
115+
text-align: left;
116+
height: 30px;
117+
color: $tc-black;
118+
background: $tc-gray-neutral-light;
119+
border: 1px solid $tc-gray-20;
120+
@include roboto;
121+
font-size: 13px;
122+
line-height: 20px;
123+
width: 100%;
124+
border-radius: 2px;
125+
position: relative;
126+
127+
.dropdown-menu-header {
128+
width: 100%;
129+
border: 0;
130+
height: 28px;
131+
line-height: 28px;
132+
margin: 0;
133+
padding: 0 0 0 10px;
134+
color: $tc-gray-50;
135+
font-size: 13px;
136+
}
137+
&:after{
138+
display: block;
139+
content: '';
140+
position: absolute;
141+
width: 10px;
142+
height: 14px;
143+
right: 11px;
144+
top: 50%;
145+
margin-top: -7px;
146+
background: url("./icon-select.png") left top no-repeat;
147+
background-size: 10px 14px;
148+
z-index:2;
149+
}
150+
.Dropdown {
151+
ul.dropdown-menu-list {
152+
padding: 10px 0px;
153+
li {
154+
padding: 0 20px;
155+
@include ellipsis;
156+
}
157+
li:hover {
158+
background-color: $tc-gray-neutral-dark;
159+
}
160+
}
161+
}
162+
}
1.03 KB
Loading
1.39 KB
Loading

src/components/NotificationsDropdown/NotificationsDropdown.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
import React, { PropTypes } from 'react'
77
import SVGIconImage from '../SVGIconImage'
8-
import { Dropdown } from 'appirio-tech-react-components'
8+
import Dropdown from '../Dropdown/Dropdown'
99
import cn from 'classnames'
1010

1111
const NotificationsDropdown = (props) => {

0 commit comments

Comments
 (0)