-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
DropdownToggle.js
115 lines (99 loc) · 2.68 KB
/
DropdownToggle.js
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Reference } from 'react-popper';
import { DropdownContext } from './DropdownContext';
import { mapToCssModules, tagPropType } from './utils';
import Button from './Button';
const propTypes = {
caret: PropTypes.bool,
color: PropTypes.string,
children: PropTypes.node,
className: PropTypes.string,
cssModule: PropTypes.object,
disabled: PropTypes.bool,
onClick: PropTypes.func,
'aria-haspopup': PropTypes.bool,
split: PropTypes.bool,
tag: tagPropType,
nav: PropTypes.bool,
};
const defaultProps = {
'aria-haspopup': true,
color: 'secondary',
};
class DropdownToggle extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick(e) {
if (this.props.disabled || this.props.context.disabled) {
e.preventDefault();
return;
}
if (this.props.nav && !this.props.tag) {
e.preventDefault();
}
if (this.props.onClick) {
this.props.onClick(e);
}
this.props.context.toggle(e);
}
render() {
const { className, color, cssModule, caret, split, nav, tag, innerRef, ...props } = this.props;
const ariaLabel = props['aria-label'] || 'Toggle Dropdown';
const classes = mapToCssModules(classNames(
className,
{
'dropdown-toggle': caret || split,
'dropdown-toggle-split': split,
'nav-link': nav
}
), cssModule);
const children = props.children || <span className="sr-only">{ariaLabel}</span>;
let Tag;
if (nav && !tag) {
Tag = 'a';
props.href = '#';
} else if (!tag) {
Tag = Button;
props.color = color;
props.cssModule = cssModule;
} else {
Tag = tag;
}
if (this.props.context.inNavbar) {
return (
<Tag
{...props}
className={classes}
onClick={this.onClick}
aria-expanded={this.props.context.isOpen}
children={children}
/>
);
}
return (
<Reference innerRef={innerRef}>
{({ ref }) => (
<Tag
{...props}
{...{ [typeof Tag === 'string' ? 'ref' : 'innerRef']: ref }}
className={classes}
onClick={this.onClick}
aria-expanded={this.props.context.isOpen}
children={children}
/>
)}
</Reference>
);
}
}
DropdownToggle.propTypes = propTypes;
DropdownToggle.defaultProps = defaultProps;
export default React.forwardRef((props, ref) => (
<DropdownContext.Consumer>
{ctx => <DropdownToggle {...props} context={ctx} ref={ref} />}
</DropdownContext.Consumer>
));