1 | import _extends from "@babel/runtime-corejs2/helpers/esm/extends";
|
2 | import _objectWithoutPropertiesLoose from "@babel/runtime-corejs2/helpers/esm/objectWithoutPropertiesLoose";
|
3 | import _inheritsLoose from "@babel/runtime-corejs2/helpers/esm/inheritsLoose";
|
4 | import classNames from 'classnames';
|
5 | import keycode from 'keycode';
|
6 | import React, { cloneElement } from 'react';
|
7 | import PropTypes from 'prop-types';
|
8 | import ReactDOM from 'react-dom';
|
9 | import all from 'prop-types-extra/lib/all';
|
10 | import warning from 'warning';
|
11 | import { bsClass, bsStyles, getClassSet, prefix, splitBsProps } from './utils/bootstrapUtils';
|
12 | import createChainedFunction from './utils/createChainedFunction';
|
13 | import ValidComponentChildren from './utils/ValidComponentChildren';
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | var propTypes = {
|
19 | |
20 |
|
21 |
|
22 |
|
23 | activeKey: PropTypes.any,
|
24 |
|
25 | |
26 |
|
27 |
|
28 | activeHref: PropTypes.string,
|
29 |
|
30 | |
31 |
|
32 |
|
33 | stacked: PropTypes.bool,
|
34 | justified: all(PropTypes.bool, function (_ref) {
|
35 | var justified = _ref.justified,
|
36 | navbar = _ref.navbar;
|
37 | return justified && navbar ? Error('justified navbar `Nav`s are not supported') : null;
|
38 | }),
|
39 |
|
40 | |
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 | onSelect: PropTypes.func,
|
51 |
|
52 | |
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | role: PropTypes.string,
|
61 |
|
62 | |
63 |
|
64 |
|
65 |
|
66 | navbar: PropTypes.bool,
|
67 |
|
68 | |
69 |
|
70 |
|
71 |
|
72 | pullRight: PropTypes.bool,
|
73 |
|
74 | |
75 |
|
76 |
|
77 |
|
78 | pullLeft: PropTypes.bool
|
79 | };
|
80 | var defaultProps = {
|
81 | justified: false,
|
82 | pullRight: false,
|
83 | pullLeft: false,
|
84 | stacked: false
|
85 | };
|
86 | var contextTypes = {
|
87 | $bs_navbar: PropTypes.shape({
|
88 | bsClass: PropTypes.string,
|
89 | onSelect: PropTypes.func
|
90 | }),
|
91 | $bs_tabContainer: PropTypes.shape({
|
92 | activeKey: PropTypes.any,
|
93 | onSelect: PropTypes.func.isRequired,
|
94 | getTabId: PropTypes.func.isRequired,
|
95 | getPaneId: PropTypes.func.isRequired
|
96 | })
|
97 | };
|
98 |
|
99 | var Nav =
|
100 |
|
101 | function (_React$Component) {
|
102 | _inheritsLoose(Nav, _React$Component);
|
103 |
|
104 | function Nav() {
|
105 | return _React$Component.apply(this, arguments) || this;
|
106 | }
|
107 |
|
108 | var _proto = Nav.prototype;
|
109 |
|
110 | _proto.componentDidUpdate = function componentDidUpdate() {
|
111 | var _this = this;
|
112 |
|
113 | if (!this._needsRefocus) {
|
114 | return;
|
115 | }
|
116 |
|
117 | this._needsRefocus = false;
|
118 | var children = this.props.children;
|
119 |
|
120 | var _this$getActiveProps = this.getActiveProps(),
|
121 | activeKey = _this$getActiveProps.activeKey,
|
122 | activeHref = _this$getActiveProps.activeHref;
|
123 |
|
124 | var activeChild = ValidComponentChildren.find(children, function (child) {
|
125 | return _this.isActive(child, activeKey, activeHref);
|
126 | });
|
127 | var childrenArray = ValidComponentChildren.toArray(children);
|
128 | var activeChildIndex = childrenArray.indexOf(activeChild);
|
129 | var childNodes = ReactDOM.findDOMNode(this).children;
|
130 | var activeNode = childNodes && childNodes[activeChildIndex];
|
131 |
|
132 | if (!activeNode || !activeNode.firstChild) {
|
133 | return;
|
134 | }
|
135 |
|
136 | activeNode.firstChild.focus();
|
137 | };
|
138 |
|
139 | _proto.getActiveProps = function getActiveProps() {
|
140 | var tabContainer = this.context.$bs_tabContainer;
|
141 |
|
142 | if (tabContainer) {
|
143 | process.env.NODE_ENV !== "production" ? warning(this.props.activeKey == null && !this.props.activeHref, 'Specifying a `<Nav>` `activeKey` or `activeHref` in the context of ' + 'a `<TabContainer>` is not supported. Instead use `<TabContainer ' + ("activeKey={" + this.props.activeKey + "} />`.")) : void 0;
|
144 | return tabContainer;
|
145 | }
|
146 |
|
147 | return this.props;
|
148 | };
|
149 |
|
150 | _proto.getNextActiveChild = function getNextActiveChild(offset) {
|
151 | var _this2 = this;
|
152 |
|
153 | var children = this.props.children;
|
154 | var validChildren = children.filter(function (child) {
|
155 | return child.props.eventKey != null && !child.props.disabled;
|
156 | });
|
157 |
|
158 | var _this$getActiveProps2 = this.getActiveProps(),
|
159 | activeKey = _this$getActiveProps2.activeKey,
|
160 | activeHref = _this$getActiveProps2.activeHref;
|
161 |
|
162 | var activeChild = ValidComponentChildren.find(children, function (child) {
|
163 | return _this2.isActive(child, activeKey, activeHref);
|
164 | });
|
165 |
|
166 | var activeChildIndex = validChildren.indexOf(activeChild);
|
167 |
|
168 | if (activeChildIndex === -1) {
|
169 |
|
170 | return validChildren[0];
|
171 | }
|
172 |
|
173 | var nextIndex = activeChildIndex + offset;
|
174 | var numValidChildren = validChildren.length;
|
175 |
|
176 | if (nextIndex >= numValidChildren) {
|
177 | nextIndex = 0;
|
178 | } else if (nextIndex < 0) {
|
179 | nextIndex = numValidChildren - 1;
|
180 | }
|
181 |
|
182 | return validChildren[nextIndex];
|
183 | };
|
184 |
|
185 | _proto.getTabProps = function getTabProps(child, tabContainer, navRole, active, onSelect) {
|
186 | var _this3 = this;
|
187 |
|
188 | if (!tabContainer && navRole !== 'tablist') {
|
189 |
|
190 | return null;
|
191 | }
|
192 |
|
193 | var _child$props = child.props,
|
194 | id = _child$props.id,
|
195 | controls = _child$props['aria-controls'],
|
196 | eventKey = _child$props.eventKey,
|
197 | role = _child$props.role,
|
198 | onKeyDown = _child$props.onKeyDown,
|
199 | tabIndex = _child$props.tabIndex;
|
200 |
|
201 | if (tabContainer) {
|
202 | process.env.NODE_ENV !== "production" ? warning(!id && !controls, 'In the context of a `<TabContainer>`, `<NavItem>`s are given ' + 'generated `id` and `aria-controls` attributes for the sake of ' + 'proper component accessibility. Any provided ones will be ignored. ' + 'To control these attributes directly, provide a `generateChildId` ' + 'prop to the parent `<TabContainer>`.') : void 0;
|
203 | id = tabContainer.getTabId(eventKey);
|
204 | controls = tabContainer.getPaneId(eventKey);
|
205 | }
|
206 |
|
207 | if (navRole === 'tablist') {
|
208 | role = role || 'tab';
|
209 | onKeyDown = createChainedFunction(function (event) {
|
210 | return _this3.handleTabKeyDown(onSelect, event);
|
211 | }, onKeyDown);
|
212 | tabIndex = active ? tabIndex : -1;
|
213 | }
|
214 |
|
215 | return {
|
216 | id: id,
|
217 | role: role,
|
218 | onKeyDown: onKeyDown,
|
219 | 'aria-controls': controls,
|
220 | tabIndex: tabIndex
|
221 | };
|
222 | };
|
223 |
|
224 | _proto.handleTabKeyDown = function handleTabKeyDown(onSelect, event) {
|
225 | var nextActiveChild;
|
226 |
|
227 | switch (event.keyCode) {
|
228 | case keycode.codes.left:
|
229 | case keycode.codes.up:
|
230 | nextActiveChild = this.getNextActiveChild(-1);
|
231 | break;
|
232 |
|
233 | case keycode.codes.right:
|
234 | case keycode.codes.down:
|
235 | nextActiveChild = this.getNextActiveChild(1);
|
236 | break;
|
237 |
|
238 | default:
|
239 |
|
240 | return;
|
241 | }
|
242 |
|
243 | event.preventDefault();
|
244 |
|
245 | if (onSelect && nextActiveChild && nextActiveChild.props.eventKey != null) {
|
246 | onSelect(nextActiveChild.props.eventKey);
|
247 | }
|
248 |
|
249 | this._needsRefocus = true;
|
250 | };
|
251 |
|
252 | _proto.isActive = function isActive(_ref2, activeKey, activeHref) {
|
253 | var props = _ref2.props;
|
254 |
|
255 | if (props.active || activeKey != null && props.eventKey === activeKey || activeHref && props.href === activeHref) {
|
256 | return true;
|
257 | }
|
258 |
|
259 | return props.active;
|
260 | };
|
261 |
|
262 | _proto.render = function render() {
|
263 | var _extends2,
|
264 | _this4 = this;
|
265 |
|
266 | var _this$props = this.props,
|
267 | stacked = _this$props.stacked,
|
268 | justified = _this$props.justified,
|
269 | onSelect = _this$props.onSelect,
|
270 | propsRole = _this$props.role,
|
271 | propsNavbar = _this$props.navbar,
|
272 | pullRight = _this$props.pullRight,
|
273 | pullLeft = _this$props.pullLeft,
|
274 | className = _this$props.className,
|
275 | children = _this$props.children,
|
276 | props = _objectWithoutPropertiesLoose(_this$props, ["stacked", "justified", "onSelect", "role", "navbar", "pullRight", "pullLeft", "className", "children"]);
|
277 |
|
278 | var tabContainer = this.context.$bs_tabContainer;
|
279 | var role = propsRole || (tabContainer ? 'tablist' : null);
|
280 |
|
281 | var _this$getActiveProps3 = this.getActiveProps(),
|
282 | activeKey = _this$getActiveProps3.activeKey,
|
283 | activeHref = _this$getActiveProps3.activeHref;
|
284 |
|
285 | delete props.activeKey;
|
286 |
|
287 | delete props.activeHref;
|
288 |
|
289 | var _splitBsProps = splitBsProps(props),
|
290 | bsProps = _splitBsProps[0],
|
291 | elementProps = _splitBsProps[1];
|
292 |
|
293 | var classes = _extends({}, getClassSet(bsProps), (_extends2 = {}, _extends2[prefix(bsProps, 'stacked')] = stacked, _extends2[prefix(bsProps, 'justified')] = justified, _extends2));
|
294 |
|
295 | var navbar = propsNavbar != null ? propsNavbar : this.context.$bs_navbar;
|
296 | var pullLeftClassName;
|
297 | var pullRightClassName;
|
298 |
|
299 | if (navbar) {
|
300 | var navbarProps = this.context.$bs_navbar || {
|
301 | bsClass: 'navbar'
|
302 | };
|
303 | classes[prefix(navbarProps, 'nav')] = true;
|
304 | pullRightClassName = prefix(navbarProps, 'right');
|
305 | pullLeftClassName = prefix(navbarProps, 'left');
|
306 | } else {
|
307 | pullRightClassName = 'pull-right';
|
308 | pullLeftClassName = 'pull-left';
|
309 | }
|
310 |
|
311 | classes[pullRightClassName] = pullRight;
|
312 | classes[pullLeftClassName] = pullLeft;
|
313 | return React.createElement("ul", _extends({}, elementProps, {
|
314 | role: role,
|
315 | className: classNames(className, classes)
|
316 | }), ValidComponentChildren.map(children, function (child) {
|
317 | var active = _this4.isActive(child, activeKey, activeHref);
|
318 |
|
319 | var childOnSelect = createChainedFunction(child.props.onSelect, onSelect, navbar && navbar.onSelect, tabContainer && tabContainer.onSelect);
|
320 | return cloneElement(child, _extends({}, _this4.getTabProps(child, tabContainer, role, active, childOnSelect), {
|
321 | active: active,
|
322 | activeKey: activeKey,
|
323 | activeHref: activeHref,
|
324 | onSelect: childOnSelect
|
325 | }));
|
326 | }));
|
327 | };
|
328 |
|
329 | return Nav;
|
330 | }(React.Component);
|
331 |
|
332 | Nav.propTypes = propTypes;
|
333 | Nav.defaultProps = defaultProps;
|
334 | Nav.contextTypes = contextTypes;
|
335 | export default bsClass('nav', bsStyles(['tabs', 'pills'], Nav)); |
\ | No newline at end of file |