UNPKG

5.19 kBJavaScriptView Raw
1import _extends from "@babel/runtime-corejs2/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime-corejs2/helpers/esm/objectWithoutPropertiesLoose";
3import _Array$from from "@babel/runtime-corejs2/core-js/array/from";
4import _inheritsLoose from "@babel/runtime-corejs2/helpers/esm/inheritsLoose";
5import _assertThisInitialized from "@babel/runtime-corejs2/helpers/esm/assertThisInitialized";
6import classNames from 'classnames';
7import keycode from 'keycode';
8import React from 'react';
9import PropTypes from 'prop-types';
10import ReactDOM from 'react-dom';
11import RootCloseWrapper from 'react-overlays/lib/RootCloseWrapper';
12import { bsClass, getClassSet, prefix, splitBsPropsAndOmit } from './utils/bootstrapUtils';
13import createChainedFunction from './utils/createChainedFunction';
14import ValidComponentChildren from './utils/ValidComponentChildren';
15var propTypes = {
16 open: PropTypes.bool,
17 pullRight: PropTypes.bool,
18 onClose: PropTypes.func,
19 labelledBy: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
20 onSelect: PropTypes.func,
21 rootCloseEvent: PropTypes.oneOf(['click', 'mousedown'])
22};
23var defaultProps = {
24 bsRole: 'menu',
25 pullRight: false
26};
27
28var DropdownMenu =
29/*#__PURE__*/
30function (_React$Component) {
31 _inheritsLoose(DropdownMenu, _React$Component);
32
33 function DropdownMenu(props) {
34 var _this;
35
36 _this = _React$Component.call(this, props) || this;
37 _this.handleRootClose = _this.handleRootClose.bind(_assertThisInitialized(_assertThisInitialized(_this)));
38 _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_assertThisInitialized(_this)));
39 return _this;
40 }
41
42 var _proto = DropdownMenu.prototype;
43
44 _proto.getFocusableMenuItems = function getFocusableMenuItems() {
45 var node = ReactDOM.findDOMNode(this);
46
47 if (!node) {
48 return [];
49 }
50
51 return _Array$from(node.querySelectorAll('[tabIndex="-1"]'));
52 };
53
54 _proto.getItemsAndActiveIndex = function getItemsAndActiveIndex() {
55 var items = this.getFocusableMenuItems();
56 var activeIndex = items.indexOf(document.activeElement);
57 return {
58 items: items,
59 activeIndex: activeIndex
60 };
61 };
62
63 _proto.focusNext = function focusNext() {
64 var _this$getItemsAndActi = this.getItemsAndActiveIndex(),
65 items = _this$getItemsAndActi.items,
66 activeIndex = _this$getItemsAndActi.activeIndex;
67
68 if (items.length === 0) {
69 return;
70 }
71
72 var nextIndex = activeIndex === items.length - 1 ? 0 : activeIndex + 1;
73 items[nextIndex].focus();
74 };
75
76 _proto.focusPrevious = function focusPrevious() {
77 var _this$getItemsAndActi2 = this.getItemsAndActiveIndex(),
78 items = _this$getItemsAndActi2.items,
79 activeIndex = _this$getItemsAndActi2.activeIndex;
80
81 if (items.length === 0) {
82 return;
83 }
84
85 var prevIndex = activeIndex === 0 ? items.length - 1 : activeIndex - 1;
86 items[prevIndex].focus();
87 };
88
89 _proto.handleKeyDown = function handleKeyDown(event) {
90 switch (event.keyCode) {
91 case keycode.codes.down:
92 this.focusNext();
93 event.preventDefault();
94 break;
95
96 case keycode.codes.up:
97 this.focusPrevious();
98 event.preventDefault();
99 break;
100
101 case keycode.codes.esc:
102 case keycode.codes.tab:
103 this.props.onClose(event, {
104 source: 'keydown'
105 });
106 break;
107
108 default:
109 }
110 };
111
112 _proto.handleRootClose = function handleRootClose(event) {
113 this.props.onClose(event, {
114 source: 'rootClose'
115 });
116 };
117
118 _proto.render = function render() {
119 var _extends2,
120 _this2 = this;
121
122 var _this$props = this.props,
123 open = _this$props.open,
124 pullRight = _this$props.pullRight,
125 labelledBy = _this$props.labelledBy,
126 onSelect = _this$props.onSelect,
127 className = _this$props.className,
128 rootCloseEvent = _this$props.rootCloseEvent,
129 children = _this$props.children,
130 props = _objectWithoutPropertiesLoose(_this$props, ["open", "pullRight", "labelledBy", "onSelect", "className", "rootCloseEvent", "children"]);
131
132 var _splitBsPropsAndOmit = splitBsPropsAndOmit(props, ['onClose']),
133 bsProps = _splitBsPropsAndOmit[0],
134 elementProps = _splitBsPropsAndOmit[1];
135
136 var classes = _extends({}, getClassSet(bsProps), (_extends2 = {}, _extends2[prefix(bsProps, 'right')] = pullRight, _extends2));
137
138 return React.createElement(RootCloseWrapper, {
139 disabled: !open,
140 onRootClose: this.handleRootClose,
141 event: rootCloseEvent
142 }, React.createElement("ul", _extends({}, elementProps, {
143 role: "menu",
144 className: classNames(className, classes),
145 "aria-labelledby": labelledBy
146 }), ValidComponentChildren.map(children, function (child) {
147 return React.cloneElement(child, {
148 onKeyDown: createChainedFunction(child.props.onKeyDown, _this2.handleKeyDown),
149 onSelect: createChainedFunction(child.props.onSelect, onSelect)
150 });
151 })));
152 };
153
154 return DropdownMenu;
155}(React.Component);
156
157DropdownMenu.propTypes = propTypes;
158DropdownMenu.defaultProps = defaultProps;
159export default bsClass('dropdown-menu', DropdownMenu);
\No newline at end of file