UNPKG

8.8 kBJavaScriptView Raw
1import _extends from "@babel/runtime-corejs2/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime-corejs2/helpers/esm/objectWithoutPropertiesLoose";
3import _inheritsLoose from "@babel/runtime-corejs2/helpers/esm/inheritsLoose";
4import _assertThisInitialized from "@babel/runtime-corejs2/helpers/esm/assertThisInitialized";
5// TODO: Remove this pragma once we upgrade eslint-config-airbnb.
6
7/* eslint-disable react/no-multi-comp */
8import classNames from 'classnames';
9import React from 'react';
10import PropTypes from 'prop-types';
11import elementType from 'prop-types-extra/lib/elementType';
12import uncontrollable from 'uncontrollable';
13import Grid from './Grid';
14import NavbarBrand from './NavbarBrand';
15import NavbarCollapse from './NavbarCollapse';
16import NavbarHeader from './NavbarHeader';
17import NavbarToggle from './NavbarToggle';
18import { bsClass as setBsClass, bsStyles, getClassSet, prefix, splitBsPropsAndOmit } from './utils/bootstrapUtils';
19import { Style } from './utils/StyleConfig';
20import createChainedFunction from './utils/createChainedFunction';
21var propTypes = {
22 /**
23 * Create a fixed navbar along the top of the screen, that scrolls with the
24 * page
25 */
26 fixedTop: PropTypes.bool,
27
28 /**
29 * Create a fixed navbar along the bottom of the screen, that scrolls with
30 * the page
31 */
32 fixedBottom: PropTypes.bool,
33
34 /**
35 * Create a full-width navbar that scrolls away with the page
36 */
37 staticTop: PropTypes.bool,
38
39 /**
40 * An alternative dark visual style for the Navbar
41 */
42 inverse: PropTypes.bool,
43
44 /**
45 * Allow the Navbar to fluidly adjust to the page or container width, instead
46 * of at the predefined screen breakpoints
47 */
48 fluid: PropTypes.bool,
49
50 /**
51 * Set a custom element for this component.
52 */
53 componentClass: elementType,
54
55 /**
56 * A callback fired when the `<Navbar>` body collapses or expands. Fired when
57 * a `<Navbar.Toggle>` is clicked and called with the new `expanded`
58 * boolean value.
59 *
60 * @controllable expanded
61 */
62 onToggle: PropTypes.func,
63
64 /**
65 * A callback fired when a descendant of a child `<Nav>` is selected. Should
66 * be used to execute complex closing or other miscellaneous actions desired
67 * after selecting a descendant of `<Nav>`. Does nothing if no `<Nav>` or `<Nav>`
68 * descendants exist. The callback is called with an eventKey, which is a
69 * prop from the selected `<Nav>` descendant, and an event.
70 *
71 * ```js
72 * function (
73 * Any eventKey,
74 * SyntheticEvent event?
75 * )
76 * ```
77 *
78 * For basic closing behavior after all `<Nav>` descendant onSelect events in
79 * mobile viewports, try using collapseOnSelect.
80 *
81 * Note: If you are manually closing the navbar using this `OnSelect` prop,
82 * ensure that you are setting `expanded` to false and not *toggling* between
83 * true and false.
84 */
85 onSelect: PropTypes.func,
86
87 /**
88 * Sets `expanded` to `false` after the onSelect event of a descendant of a
89 * child `<Nav>`. Does nothing if no `<Nav>` or `<Nav>` descendants exist.
90 *
91 * The onSelect callback should be used instead for more complex operations
92 * that need to be executed after the `select` event of `<Nav>` descendants.
93 */
94 collapseOnSelect: PropTypes.bool,
95
96 /**
97 * Explicitly set the visiblity of the navbar body
98 *
99 * @controllable onToggle
100 */
101 expanded: PropTypes.bool,
102 role: PropTypes.string
103};
104var defaultProps = {
105 componentClass: 'nav',
106 fixedTop: false,
107 fixedBottom: false,
108 staticTop: false,
109 inverse: false,
110 fluid: false,
111 collapseOnSelect: false
112};
113var childContextTypes = {
114 $bs_navbar: PropTypes.shape({
115 bsClass: PropTypes.string,
116 expanded: PropTypes.bool,
117 onToggle: PropTypes.func.isRequired,
118 onSelect: PropTypes.func
119 })
120};
121
122var Navbar =
123/*#__PURE__*/
124function (_React$Component) {
125 _inheritsLoose(Navbar, _React$Component);
126
127 function Navbar(props, context) {
128 var _this;
129
130 _this = _React$Component.call(this, props, context) || this;
131 _this.handleToggle = _this.handleToggle.bind(_assertThisInitialized(_assertThisInitialized(_this)));
132 _this.handleCollapse = _this.handleCollapse.bind(_assertThisInitialized(_assertThisInitialized(_this)));
133 return _this;
134 }
135
136 var _proto = Navbar.prototype;
137
138 _proto.getChildContext = function getChildContext() {
139 var _this$props = this.props,
140 bsClass = _this$props.bsClass,
141 expanded = _this$props.expanded,
142 onSelect = _this$props.onSelect,
143 collapseOnSelect = _this$props.collapseOnSelect;
144 return {
145 $bs_navbar: {
146 bsClass: bsClass,
147 expanded: expanded,
148 onToggle: this.handleToggle,
149 onSelect: createChainedFunction(onSelect, collapseOnSelect ? this.handleCollapse : null)
150 }
151 };
152 };
153
154 _proto.handleCollapse = function handleCollapse() {
155 var _this$props2 = this.props,
156 onToggle = _this$props2.onToggle,
157 expanded = _this$props2.expanded;
158
159 if (expanded) {
160 onToggle(false);
161 }
162 };
163
164 _proto.handleToggle = function handleToggle() {
165 var _this$props3 = this.props,
166 onToggle = _this$props3.onToggle,
167 expanded = _this$props3.expanded;
168 onToggle(!expanded);
169 };
170
171 _proto.render = function render() {
172 var _extends2;
173
174 var _this$props4 = this.props,
175 Component = _this$props4.componentClass,
176 fixedTop = _this$props4.fixedTop,
177 fixedBottom = _this$props4.fixedBottom,
178 staticTop = _this$props4.staticTop,
179 inverse = _this$props4.inverse,
180 fluid = _this$props4.fluid,
181 className = _this$props4.className,
182 children = _this$props4.children,
183 props = _objectWithoutPropertiesLoose(_this$props4, ["componentClass", "fixedTop", "fixedBottom", "staticTop", "inverse", "fluid", "className", "children"]);
184
185 var _splitBsPropsAndOmit = splitBsPropsAndOmit(props, ['expanded', 'onToggle', 'onSelect', 'collapseOnSelect']),
186 bsProps = _splitBsPropsAndOmit[0],
187 elementProps = _splitBsPropsAndOmit[1]; // will result in some false positives but that seems better
188 // than false negatives. strict `undefined` check allows explicit
189 // "nulling" of the role if the user really doesn't want one
190
191
192 if (elementProps.role === undefined && Component !== 'nav') {
193 elementProps.role = 'navigation';
194 }
195
196 if (inverse) {
197 bsProps.bsStyle = Style.INVERSE;
198 }
199
200 var classes = _extends({}, getClassSet(bsProps), (_extends2 = {}, _extends2[prefix(bsProps, 'fixed-top')] = fixedTop, _extends2[prefix(bsProps, 'fixed-bottom')] = fixedBottom, _extends2[prefix(bsProps, 'static-top')] = staticTop, _extends2));
201
202 return React.createElement(Component, _extends({}, elementProps, {
203 className: classNames(className, classes)
204 }), React.createElement(Grid, {
205 fluid: fluid
206 }, children));
207 };
208
209 return Navbar;
210}(React.Component);
211
212Navbar.propTypes = propTypes;
213Navbar.defaultProps = defaultProps;
214Navbar.childContextTypes = childContextTypes;
215setBsClass('navbar', Navbar);
216var UncontrollableNavbar = uncontrollable(Navbar, {
217 expanded: 'onToggle'
218});
219
220function createSimpleWrapper(tag, suffix, displayName) {
221 var Wrapper = function Wrapper(_ref, _ref2) {
222 var Component = _ref.componentClass,
223 className = _ref.className,
224 pullRight = _ref.pullRight,
225 pullLeft = _ref.pullLeft,
226 props = _objectWithoutPropertiesLoose(_ref, ["componentClass", "className", "pullRight", "pullLeft"]);
227
228 var _ref2$$bs_navbar = _ref2.$bs_navbar,
229 navbarProps = _ref2$$bs_navbar === void 0 ? {
230 bsClass: 'navbar'
231 } : _ref2$$bs_navbar;
232 return React.createElement(Component, _extends({}, props, {
233 className: classNames(className, prefix(navbarProps, suffix), pullRight && prefix(navbarProps, 'right'), pullLeft && prefix(navbarProps, 'left'))
234 }));
235 };
236
237 Wrapper.displayName = displayName;
238 Wrapper.propTypes = {
239 componentClass: elementType,
240 pullRight: PropTypes.bool,
241 pullLeft: PropTypes.bool
242 };
243 Wrapper.defaultProps = {
244 componentClass: tag,
245 pullRight: false,
246 pullLeft: false
247 };
248 Wrapper.contextTypes = {
249 $bs_navbar: PropTypes.shape({
250 bsClass: PropTypes.string
251 })
252 };
253 return Wrapper;
254}
255
256UncontrollableNavbar.Brand = NavbarBrand;
257UncontrollableNavbar.Header = NavbarHeader;
258UncontrollableNavbar.Toggle = NavbarToggle;
259UncontrollableNavbar.Collapse = NavbarCollapse;
260UncontrollableNavbar.Form = createSimpleWrapper('div', 'form', 'NavbarForm');
261UncontrollableNavbar.Text = createSimpleWrapper('p', 'text', 'NavbarText');
262UncontrollableNavbar.Link = createSimpleWrapper('a', 'link', 'NavbarLink'); // Set bsStyles here so they can be overridden.
263
264export default bsStyles([Style.DEFAULT, Style.INVERSE], Style.DEFAULT, UncontrollableNavbar);
\No newline at end of file