UNPKG

8.43 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";
5import classNames from 'classnames';
6import React from 'react';
7import PropTypes from 'prop-types';
8import elementType from 'prop-types-extra/lib/elementType';
9import warning from 'warning';
10import { bsClass, getClassSet, prefix, splitBsPropsAndOmit } from './utils/bootstrapUtils';
11import createChainedFunction from './utils/createChainedFunction';
12import Fade from './Fade';
13var propTypes = {
14 /**
15 * Uniquely identify the `<TabPane>` among its siblings.
16 */
17 eventKey: PropTypes.any,
18
19 /**
20 * Use animation when showing or hiding `<TabPane>`s. Use `false` to disable,
21 * `true` to enable the default `<Fade>` animation or
22 * a react-transition-group v2 `<Transition/>` component.
23 */
24 animation: PropTypes.oneOfType([PropTypes.bool, elementType]),
25
26 /** @private * */
27 id: PropTypes.string,
28
29 /** @private * */
30 'aria-labelledby': PropTypes.string,
31
32 /**
33 * If not explicitly specified and rendered in the context of a
34 * `<TabContent>`, the `bsClass` of the `<TabContent>` suffixed by `-pane`.
35 * If otherwise not explicitly specified, `tab-pane`.
36 */
37 bsClass: PropTypes.string,
38
39 /**
40 * Transition onEnter callback when animation is not `false`
41 */
42 onEnter: PropTypes.func,
43
44 /**
45 * Transition onEntering callback when animation is not `false`
46 */
47 onEntering: PropTypes.func,
48
49 /**
50 * Transition onEntered callback when animation is not `false`
51 */
52 onEntered: PropTypes.func,
53
54 /**
55 * Transition onExit callback when animation is not `false`
56 */
57 onExit: PropTypes.func,
58
59 /**
60 * Transition onExiting callback when animation is not `false`
61 */
62 onExiting: PropTypes.func,
63
64 /**
65 * Transition onExited callback when animation is not `false`
66 */
67 onExited: PropTypes.func,
68
69 /**
70 * Wait until the first "enter" transition to mount the tab (add it to the DOM)
71 */
72 mountOnEnter: PropTypes.bool,
73
74 /**
75 * Unmount the tab (remove it from the DOM) when it is no longer visible
76 */
77 unmountOnExit: PropTypes.bool
78};
79var contextTypes = {
80 $bs_tabContainer: PropTypes.shape({
81 getTabId: PropTypes.func,
82 getPaneId: PropTypes.func
83 }),
84 $bs_tabContent: PropTypes.shape({
85 bsClass: PropTypes.string,
86 animation: PropTypes.oneOfType([PropTypes.bool, elementType]),
87 activeKey: PropTypes.any,
88 mountOnEnter: PropTypes.bool,
89 unmountOnExit: PropTypes.bool,
90 onPaneEnter: PropTypes.func.isRequired,
91 onPaneExited: PropTypes.func.isRequired,
92 exiting: PropTypes.bool.isRequired
93 })
94};
95/**
96 * We override the `<TabContainer>` context so `<Nav>`s in `<TabPane>`s don't
97 * conflict with the top level one.
98 */
99
100var childContextTypes = {
101 $bs_tabContainer: PropTypes.oneOf([null])
102};
103
104var TabPane =
105/*#__PURE__*/
106function (_React$Component) {
107 _inheritsLoose(TabPane, _React$Component);
108
109 function TabPane(props, context) {
110 var _this;
111
112 _this = _React$Component.call(this, props, context) || this;
113 _this.handleEnter = _this.handleEnter.bind(_assertThisInitialized(_assertThisInitialized(_this)));
114 _this.handleExited = _this.handleExited.bind(_assertThisInitialized(_assertThisInitialized(_this)));
115 _this.in = false;
116 return _this;
117 }
118
119 var _proto = TabPane.prototype;
120
121 _proto.getChildContext = function getChildContext() {
122 return {
123 $bs_tabContainer: null
124 };
125 };
126
127 _proto.componentDidMount = function componentDidMount() {
128 if (this.shouldBeIn()) {
129 // In lieu of the action event firing.
130 this.handleEnter();
131 }
132 };
133
134 _proto.componentDidUpdate = function componentDidUpdate() {
135 if (this.in) {
136 if (!this.shouldBeIn()) {
137 // We shouldn't be active any more. Notify the parent.
138 this.handleExited();
139 }
140 } else if (this.shouldBeIn()) {
141 // We are the active child. Notify the parent.
142 this.handleEnter();
143 }
144 };
145
146 _proto.componentWillUnmount = function componentWillUnmount() {
147 if (this.in) {
148 // In lieu of the action event firing.
149 this.handleExited();
150 }
151 };
152
153 _proto.getAnimation = function getAnimation() {
154 if (this.props.animation != null) {
155 return this.props.animation;
156 }
157
158 var tabContent = this.context.$bs_tabContent;
159 return tabContent && tabContent.animation;
160 };
161
162 _proto.handleEnter = function handleEnter() {
163 var tabContent = this.context.$bs_tabContent;
164
165 if (!tabContent) {
166 return;
167 }
168
169 this.in = tabContent.onPaneEnter(this, this.props.eventKey);
170 };
171
172 _proto.handleExited = function handleExited() {
173 var tabContent = this.context.$bs_tabContent;
174
175 if (!tabContent) {
176 return;
177 }
178
179 tabContent.onPaneExited(this);
180 this.in = false;
181 };
182
183 _proto.isActive = function isActive() {
184 var tabContent = this.context.$bs_tabContent;
185 var activeKey = tabContent && tabContent.activeKey;
186 return this.props.eventKey === activeKey;
187 };
188
189 _proto.shouldBeIn = function shouldBeIn() {
190 return this.getAnimation() && this.isActive();
191 };
192
193 _proto.render = function render() {
194 var _this$props = this.props,
195 eventKey = _this$props.eventKey,
196 className = _this$props.className,
197 onEnter = _this$props.onEnter,
198 onEntering = _this$props.onEntering,
199 onEntered = _this$props.onEntered,
200 onExit = _this$props.onExit,
201 onExiting = _this$props.onExiting,
202 onExited = _this$props.onExited,
203 propsMountOnEnter = _this$props.mountOnEnter,
204 propsUnmountOnExit = _this$props.unmountOnExit,
205 props = _objectWithoutPropertiesLoose(_this$props, ["eventKey", "className", "onEnter", "onEntering", "onEntered", "onExit", "onExiting", "onExited", "mountOnEnter", "unmountOnExit"]);
206
207 var _this$context = this.context,
208 tabContent = _this$context.$bs_tabContent,
209 tabContainer = _this$context.$bs_tabContainer;
210
211 var _splitBsPropsAndOmit = splitBsPropsAndOmit(props, ['animation']),
212 bsProps = _splitBsPropsAndOmit[0],
213 elementProps = _splitBsPropsAndOmit[1];
214
215 var active = this.isActive();
216 var animation = this.getAnimation();
217 var mountOnEnter = propsMountOnEnter != null ? propsMountOnEnter : tabContent && tabContent.mountOnEnter;
218 var unmountOnExit = propsUnmountOnExit != null ? propsUnmountOnExit : tabContent && tabContent.unmountOnExit;
219
220 if (!active && !animation && unmountOnExit) {
221 return null;
222 }
223
224 var Transition = animation === true ? Fade : animation || null;
225
226 if (tabContent) {
227 bsProps.bsClass = prefix(tabContent, 'pane');
228 }
229
230 var classes = _extends({}, getClassSet(bsProps), {
231 active: active
232 });
233
234 if (tabContainer) {
235 process.env.NODE_ENV !== "production" ? warning(!elementProps.id && !elementProps['aria-labelledby'], 'In the context of a `<TabContainer>`, `<TabPanes>` are given ' + 'generated `id` and `aria-labelledby` 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;
236 elementProps.id = tabContainer.getPaneId(eventKey);
237 elementProps['aria-labelledby'] = tabContainer.getTabId(eventKey);
238 }
239
240 var pane = React.createElement("div", _extends({}, elementProps, {
241 role: "tabpanel",
242 "aria-hidden": !active,
243 className: classNames(className, classes)
244 }));
245
246 if (Transition) {
247 var exiting = tabContent && tabContent.exiting;
248 return React.createElement(Transition, {
249 in: active && !exiting,
250 onEnter: createChainedFunction(this.handleEnter, onEnter),
251 onEntering: onEntering,
252 onEntered: onEntered,
253 onExit: onExit,
254 onExiting: onExiting,
255 onExited: createChainedFunction(this.handleExited, onExited),
256 mountOnEnter: mountOnEnter,
257 unmountOnExit: unmountOnExit
258 }, pane);
259 }
260
261 return pane;
262 };
263
264 return TabPane;
265}(React.Component);
266
267TabPane.propTypes = propTypes;
268TabPane.contextTypes = contextTypes;
269TabPane.childContextTypes = childContextTypes;
270export default bsClass('tab-pane', TabPane);
\No newline at end of file