UNPKG

7.06 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
5import _typeof from "@babel/runtime/helpers/esm/typeof";
6import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
7var _excluded = ["id", "prefixCls", "className", "items", "direction", "activeKey", "defaultActiveKey", "editable", "animated", "tabPosition", "tabBarGutter", "tabBarStyle", "tabBarExtraContent", "locale", "moreIcon", "moreTransitionName", "destroyInactiveTabPane", "renderTabBar", "onChange", "onTabClick", "onTabScroll", "getPopupContainer", "popupClassName", "indicatorSize"];
8// Accessibility https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role
9import * as React from 'react';
10import { useEffect, useState } from 'react';
11import classNames from 'classnames';
12import isMobile from "rc-util/es/isMobile";
13import useMergedState from "rc-util/es/hooks/useMergedState";
14import TabPanelList from "./TabPanelList";
15import TabContext from "./TabContext";
16import TabNavListWrapper from "./TabNavList/Wrapper";
17import useAnimateConfig from "./hooks/useAnimateConfig";
18/**
19 * Should added antd:
20 * - type
21 *
22 * Removed:
23 * - onNextClick
24 * - onPrevClick
25 * - keyboard
26 */ // Used for accessibility
27var uuid = 0;
28function Tabs(_ref, ref) {
29 var _classNames;
30 var id = _ref.id,
31 _ref$prefixCls = _ref.prefixCls,
32 prefixCls = _ref$prefixCls === void 0 ? 'rc-tabs' : _ref$prefixCls,
33 className = _ref.className,
34 items = _ref.items,
35 direction = _ref.direction,
36 activeKey = _ref.activeKey,
37 defaultActiveKey = _ref.defaultActiveKey,
38 editable = _ref.editable,
39 animated = _ref.animated,
40 _ref$tabPosition = _ref.tabPosition,
41 tabPosition = _ref$tabPosition === void 0 ? 'top' : _ref$tabPosition,
42 tabBarGutter = _ref.tabBarGutter,
43 tabBarStyle = _ref.tabBarStyle,
44 tabBarExtraContent = _ref.tabBarExtraContent,
45 locale = _ref.locale,
46 moreIcon = _ref.moreIcon,
47 moreTransitionName = _ref.moreTransitionName,
48 destroyInactiveTabPane = _ref.destroyInactiveTabPane,
49 renderTabBar = _ref.renderTabBar,
50 onChange = _ref.onChange,
51 onTabClick = _ref.onTabClick,
52 onTabScroll = _ref.onTabScroll,
53 getPopupContainer = _ref.getPopupContainer,
54 popupClassName = _ref.popupClassName,
55 indicatorSize = _ref.indicatorSize,
56 restProps = _objectWithoutProperties(_ref, _excluded);
57 var tabs = React.useMemo(function () {
58 return (items || []).filter(function (item) {
59 return item && _typeof(item) === 'object' && 'key' in item;
60 });
61 }, [items]);
62 var rtl = direction === 'rtl';
63 var mergedAnimated = useAnimateConfig(animated);
64
65 // ======================== Mobile ========================
66 var _useState = useState(false),
67 _useState2 = _slicedToArray(_useState, 2),
68 mobile = _useState2[0],
69 setMobile = _useState2[1];
70 useEffect(function () {
71 // Only update on the client side
72 setMobile(isMobile());
73 }, []);
74
75 // ====================== Active Key ======================
76 var _useMergedState = useMergedState(function () {
77 var _tabs$;
78 return (_tabs$ = tabs[0]) === null || _tabs$ === void 0 ? void 0 : _tabs$.key;
79 }, {
80 value: activeKey,
81 defaultValue: defaultActiveKey
82 }),
83 _useMergedState2 = _slicedToArray(_useMergedState, 2),
84 mergedActiveKey = _useMergedState2[0],
85 setMergedActiveKey = _useMergedState2[1];
86 var _useState3 = useState(function () {
87 return tabs.findIndex(function (tab) {
88 return tab.key === mergedActiveKey;
89 });
90 }),
91 _useState4 = _slicedToArray(_useState3, 2),
92 activeIndex = _useState4[0],
93 setActiveIndex = _useState4[1];
94
95 // Reset active key if not exist anymore
96 useEffect(function () {
97 var newActiveIndex = tabs.findIndex(function (tab) {
98 return tab.key === mergedActiveKey;
99 });
100 if (newActiveIndex === -1) {
101 var _tabs$newActiveIndex;
102 newActiveIndex = Math.max(0, Math.min(activeIndex, tabs.length - 1));
103 setMergedActiveKey((_tabs$newActiveIndex = tabs[newActiveIndex]) === null || _tabs$newActiveIndex === void 0 ? void 0 : _tabs$newActiveIndex.key);
104 }
105 setActiveIndex(newActiveIndex);
106 }, [tabs.map(function (tab) {
107 return tab.key;
108 }).join('_'), mergedActiveKey, activeIndex]);
109
110 // ===================== Accessibility ====================
111 var _useMergedState3 = useMergedState(null, {
112 value: id
113 }),
114 _useMergedState4 = _slicedToArray(_useMergedState3, 2),
115 mergedId = _useMergedState4[0],
116 setMergedId = _useMergedState4[1];
117
118 // Async generate id to avoid ssr mapping failed
119 useEffect(function () {
120 if (!id) {
121 setMergedId("rc-tabs-".concat(process.env.NODE_ENV === 'test' ? 'test' : uuid));
122 uuid += 1;
123 }
124 }, []);
125
126 // ======================== Events ========================
127 function onInternalTabClick(key, e) {
128 onTabClick === null || onTabClick === void 0 ? void 0 : onTabClick(key, e);
129 var isActiveChanged = key !== mergedActiveKey;
130 setMergedActiveKey(key);
131 if (isActiveChanged) {
132 onChange === null || onChange === void 0 ? void 0 : onChange(key);
133 }
134 }
135
136 // ======================== Render ========================
137 var sharedProps = {
138 id: mergedId,
139 activeKey: mergedActiveKey,
140 animated: mergedAnimated,
141 tabPosition: tabPosition,
142 rtl: rtl,
143 mobile: mobile
144 };
145 var tabNavBarProps = _objectSpread(_objectSpread({}, sharedProps), {}, {
146 editable: editable,
147 locale: locale,
148 moreIcon: moreIcon,
149 moreTransitionName: moreTransitionName,
150 tabBarGutter: tabBarGutter,
151 onTabClick: onInternalTabClick,
152 onTabScroll: onTabScroll,
153 extra: tabBarExtraContent,
154 style: tabBarStyle,
155 panes: null,
156 getPopupContainer: getPopupContainer,
157 popupClassName: popupClassName,
158 indicatorSize: indicatorSize
159 });
160 return /*#__PURE__*/React.createElement(TabContext.Provider, {
161 value: {
162 tabs: tabs,
163 prefixCls: prefixCls
164 }
165 }, /*#__PURE__*/React.createElement("div", _extends({
166 ref: ref,
167 id: id,
168 className: classNames(prefixCls, "".concat(prefixCls, "-").concat(tabPosition), (_classNames = {}, _defineProperty(_classNames, "".concat(prefixCls, "-mobile"), mobile), _defineProperty(_classNames, "".concat(prefixCls, "-editable"), editable), _defineProperty(_classNames, "".concat(prefixCls, "-rtl"), rtl), _classNames), className)
169 }, restProps), /*#__PURE__*/React.createElement(TabNavListWrapper, _extends({}, tabNavBarProps, {
170 renderTabBar: renderTabBar
171 })), /*#__PURE__*/React.createElement(TabPanelList, _extends({
172 destroyInactiveTabPane: destroyInactiveTabPane
173 }, sharedProps, {
174 animated: mergedAnimated
175 }))));
176}
177var ForwardTabs = /*#__PURE__*/React.forwardRef(Tabs);
178if (process.env.NODE_ENV !== 'production') {
179 ForwardTabs.displayName = 'Tabs';
180}
181export default ForwardTabs;
\No newline at end of file